Backed out 8 changesets (bug 1251482, bug 1251494, bug 1251473, bug 1239870) for gtest failures
authorWes Kocher <wkocher@mozilla.com>
Fri, 26 Feb 2016 17:14:57 -0800
changeset 322242 22424f6eeb30b9bea2a2818178e72ef46871ebbc
parent 322241 2d8118073de1024df419bb3879e7a7e0e2427aea
child 322243 542d4cda794bb670b1483e9151c34fb06b8ce8fb
push id5913
push userjlund@mozilla.com
push dateMon, 25 Apr 2016 16:57:49 +0000
treeherdermozilla-beta@dcaf0a6fa115 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1251482, 1251494, 1251473, 1239870
milestone47.0a1
backs outf064a5efbb8c8d40bebef0ff0f142cc17ea40ad5
9e33adec1aa6ad104fda36cd417d33043fe47a08
ab0347657e25475064c29a193d5505075500901a
1d385d4f195d718b74177e7f10ebf1df87496dfe
ceb3e1ee7dda59c010b172a8c13b872a4fa65220
8574075bf42f47cde9692541b5e345ff6844c073
ba077a3afbc702e15fe5a727dc00aabfc4f1becc
eb99ab06414dd713fb54f428c54d1a958cdd32ac
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
Backed out 8 changesets (bug 1251482, bug 1251494, bug 1251473, bug 1239870) for gtest failures Backed out changeset f064a5efbb8c (bug 1251494) Backed out changeset 9e33adec1aa6 (bug 1251482) Backed out changeset ab0347657e25 (bug 1251473) Backed out changeset 1d385d4f195d (bug 1239870) Backed out changeset ceb3e1ee7dda (bug 1239870) Backed out changeset 8574075bf42f (bug 1239870) Backed out changeset ba077a3afbc7 (bug 1239870) Backed out changeset eb99ab06414d (bug 1239870) MozReview-Commit-ID: 7r9SEk4VGNU
dom/media/AudioSegment.cpp
dom/media/AudioSegment.h
dom/media/VideoSegment.cpp
dom/media/VideoSegment.h
dom/media/standalone/moz.build
media/mtransport/nricectx.cpp
media/mtransport/nricectx.h
media/mtransport/test/TestSyncRunnable.cpp
media/mtransport/test/buffered_stun_socket_unittest.cpp
media/mtransport/test/gtest_ringbuffer_dumper.h
media/mtransport/test/gtest_utils.h
media/mtransport/test/ice_unittest.cpp
media/mtransport/test/moz.build
media/mtransport/test/mtransport_test_utils.h
media/mtransport/test/multi_tcp_socket_unittest.cpp
media/mtransport/test/nrappkit_unittest.cpp
media/mtransport/test/proxy_tunnel_socket_unittest.cpp
media/mtransport/test/rlogringbuffer_unittest.cpp
media/mtransport/test/runnable_utils_unittest.cpp
media/mtransport/test/sctp_unittest.cpp
media/mtransport/test/simpletokenbucket_unittest.cpp
media/mtransport/test/sockettransportservice_unittest.cpp
media/mtransport/test/test_nr_socket_unittest.cpp
media/mtransport/test/transport_unittests.cpp
media/mtransport/test/turn_unittest.cpp
media/webrtc/signaling/test/jsep_session_unittest.cpp
media/webrtc/signaling/test/jsep_track_unittest.cpp
media/webrtc/signaling/test/mediapipeline_unittest.cpp
media/webrtc/signaling/test/sdp_unittests.cpp
xpcom/base/Logging.h
xpcom/base/nsDebugImpl.cpp
xpcom/base/nsIMemoryReporter.idl
xpcom/build/FileLocation.cpp
xpcom/build/FileLocation.h
xpcom/build/ServiceList.h
xpcom/build/Services.cpp
xpcom/components/ManifestParser.h
xpcom/components/nsCategoryManager.cpp
xpcom/components/nsComponentManager.cpp
xpcom/components/nsComponentManager.h
xpcom/ds/nsObserverService.cpp
xpcom/glue/BlockingResourceBase.cpp
xpcom/glue/nsISupportsImpl.h
xpcom/libxpcomrt/XPCOMRTInit.cpp
xpcom/libxpcomrt/XPCOMRTInit.h
xpcom/libxpcomrt/XPCOMRTModule.inc
xpcom/libxpcomrt/XPCOMRTStubs.cpp
xpcom/libxpcomrt/docs/index.rst
xpcom/libxpcomrt/moz.build
xpcom/moz.build
xpcom/threads/LazyIdleThread.cpp
xpcom/threads/nsThread.cpp
xpcom/threads/nsTimerImpl.cpp
--- a/dom/media/AudioSegment.cpp
+++ b/dom/media/AudioSegment.cpp
@@ -194,22 +194,24 @@ AudioSegment::WriteTo(uint64_t aID, Audi
         PodZero(buf.Elements() + offset, c.mDuration * aOutputChannels);
         break;
       default:
         MOZ_ASSERT(false, "Not handled");
     }
 
     offset += c.mDuration * aOutputChannels;
 
+#if !defined(MOZILLA_XPCOMRT_API)
     if (!c.mTimeStamp.IsNull()) {
       TimeStamp now = TimeStamp::Now();
       // would be more efficient to c.mTimeStamp to ms on create time then pass here
       LogTime(AsyncLatencyLogger::AudioMediaStreamTrack, aID,
               (now - c.mTimeStamp).ToMilliseconds(), c.mTimeStamp);
     }
+#endif // !defined(MOZILLA_XPCOMRT_API)
   }
 
   if (offset) {
     aMixer.Mix(buf.Elements(), aOutputChannels, offset / aOutputChannels, aSampleRate);
   }
 }
 
 } // namespace mozilla
--- a/dom/media/AudioSegment.h
+++ b/dom/media/AudioSegment.h
@@ -262,30 +262,36 @@ public:
         c.mDuration = (c.mDuration * aOutRate) / aInRate;
         mDuration += c.mDuration;
         continue;
       }
       uint32_t channels = c.mChannelData.Length();
       MOZ_ASSERT(channels == segmentChannelCount);
       output.SetLength(channels);
       bufferPtrs.SetLength(channels);
+#if !defined(MOZILLA_XPCOMRT_API)
+// FIXME Bug 1126414 - XPCOMRT does not support dom::WebAudioUtils::SpeexResamplerProcess
       uint32_t inFrames = c.mDuration;
+#endif // !defined(MOZILLA_XPCOMRT_API)
       // Round up to allocate; the last frame may not be used.
       NS_ASSERTION((UINT32_MAX - aInRate + 1) / c.mDuration >= aOutRate,
                    "Dropping samples");
       uint32_t outSize = (c.mDuration * aOutRate + aInRate - 1) / aInRate;
       for (uint32_t i = 0; i < channels; i++) {
         T* out = output[i].AppendElements(outSize);
         uint32_t outFrames = outSize;
 
+#if !defined(MOZILLA_XPCOMRT_API)
+// FIXME Bug 1126414 - XPCOMRT does not support dom::WebAudioUtils::SpeexResamplerProcess
         const T* in = static_cast<const T*>(c.mChannelData[i]);
         dom::WebAudioUtils::SpeexResamplerProcess(aResampler, i,
                                                   in, &inFrames,
                                                   out, &outFrames);
         MOZ_ASSERT(inFrames == c.mDuration);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
         bufferPtrs[i] = out;
         output[i].SetLength(outFrames);
       }
       MOZ_ASSERT(channels > 0);
       c.mDuration = output[0].Length();
       c.mBuffer = new mozilla::SharedChannelArrayBuffer<T>(&output);
       for (uint32_t i = 0; i < channels; i++) {
--- a/dom/media/VideoSegment.cpp
+++ b/dom/media/VideoSegment.cpp
@@ -34,16 +34,17 @@ VideoFrame::SetNull() {
 void
 VideoFrame::TakeFrom(VideoFrame* aFrame)
 {
   mImage = aFrame->mImage.forget();
   mIntrinsicSize = aFrame->mIntrinsicSize;
   mForceBlack = aFrame->GetForceBlack();
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
 /* static */ already_AddRefed<Image>
 VideoFrame::CreateBlackImage(const gfx::IntSize& aSize)
 {
   RefPtr<ImageContainer> container = LayerManager::CreateImageContainer();
   RefPtr<PlanarYCbCrImage> image = container->CreatePlanarYCbCrImage();
   if (!image) {
     MOZ_ASSERT(false);
     return nullptr;
@@ -78,16 +79,17 @@ VideoFrame::CreateBlackImage(const gfx::
   // SetData copies data, so we can free data.
   if (!image->SetData(data)) {
     MOZ_ASSERT(false);
     return nullptr;
   }
 
   return image.forget();
 }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 VideoChunk::VideoChunk()
 {}
 
 VideoChunk::~VideoChunk()
 {}
 
 void
--- a/dom/media/VideoSegment.h
+++ b/dom/media/VideoSegment.h
@@ -5,27 +5,35 @@
 
 #ifndef MOZILLA_VIDEOSEGMENT_H_
 #define MOZILLA_VIDEOSEGMENT_H_
 
 #include "MediaSegment.h"
 #include "nsCOMPtr.h"
 #include "gfxPoint.h"
 #include "nsAutoPtr.h"
+#if defined(MOZILLA_XPCOMRT_API)
+#include "SimpleImageBuffer.h"
+#else
 #include "ImageContainer.h"
+#endif
 
 namespace mozilla {
 
 namespace layers {
 class Image;
 } // namespace layers
 
 class VideoFrame {
 public:
+#if defined(MOZILLA_XPCOMRT_API)
+  typedef mozilla::SimpleImageBuffer Image;
+#else
   typedef mozilla::layers::Image Image;
+#endif
 
   VideoFrame(already_AddRefed<Image>& aImage, const gfx::IntSize& aIntrinsicSize);
   VideoFrame();
   ~VideoFrame();
 
   bool operator==(const VideoFrame& aFrame) const
   {
     return mIntrinsicSize == aFrame.mIntrinsicSize &&
@@ -39,18 +47,20 @@ public:
 
   Image* GetImage() const { return mImage; }
   void SetForceBlack(bool aForceBlack) { mForceBlack = aForceBlack; }
   bool GetForceBlack() const { return mForceBlack; }
   const gfx::IntSize& GetIntrinsicSize() const { return mIntrinsicSize; }
   void SetNull();
   void TakeFrom(VideoFrame* aFrame);
 
+#if !defined(MOZILLA_XPCOMRT_API)
   // Create a planar YCbCr black image.
   static already_AddRefed<Image> CreateBlackImage(const gfx::IntSize& aSize);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 protected:
   // mImage can be null to indicate "no video" (aka "empty frame"). It can
   // still have an intrinsic size in this case.
   RefPtr<Image> mImage;
   // The desired size to render the video frame at.
   gfx::IntSize mIntrinsicSize;
   bool mForceBlack;
@@ -88,17 +98,21 @@ struct VideoChunk {
 
   StreamTime mDuration;
   VideoFrame mFrame;
   mozilla::TimeStamp mTimeStamp;
 };
 
 class VideoSegment : public MediaSegmentBase<VideoSegment, VideoChunk> {
 public:
+#if defined(MOZILLA_XPCOMRT_API)
+  typedef mozilla::SimpleImageBuffer Image;
+#else
   typedef mozilla::layers::Image Image;
+#endif
   typedef mozilla::gfx::IntSize IntSize;
 
   VideoSegment();
   ~VideoSegment();
 
   void AppendFrame(already_AddRefed<Image>&& aImage,
                    StreamTime aDuration,
                    const IntSize& aIntrinsicSize,
--- a/dom/media/standalone/moz.build
+++ b/dom/media/standalone/moz.build
@@ -28,16 +28,17 @@ LOCAL_INCLUDES += [
 
 if CONFIG['MOZ_WEBRTC']:
     LOCAL_INCLUDES += [
         '/media/webrtc/signaling/src/common',
         '/media/webrtc/trunk',
     ]
 
 DEFINES['MOZILLA_INTERNAL_API'] = True
+DEFINES['MOZILLA_XPCOMRT_API'] = True
 DEFINES['MOZILLA_EXTERNAL_LINKAGE'] = True
 
 include('/ipc/chromium/chromium-config.mozbuild')
 
 # Suppress some GCC warnings being treated as errors:
 #  - about attributes on forward declarations for types that are already
 #    defined, which complains about an important MOZ_EXPORT for android::AString
 if CONFIG['GNU_CC']:
--- a/media/mtransport/nricectx.cpp
+++ b/media/mtransport/nricectx.cpp
@@ -391,20 +391,25 @@ void NrIceCtx::trickle_cb(void *arg, nr_
     return;
 
   MOZ_MTLOG(ML_INFO, "NrIceCtx(" << ctx->name_ << "): trickling candidate "
             << candidate_str);
 
   s->SignalCandidate(s, candidate_str);
 }
 
-void NrIceCtx::Init(bool allow_loopback,
-                    bool tcp_enabled,
-                    bool allow_link_local)
-{
+RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
+                                  bool offerer,
+                                  bool allow_loopback,
+                                  bool tcp_enabled,
+                                  bool allow_link_local,
+                                  bool hide_non_default,
+                                  Policy policy) {
+   RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer, policy);
+
   // Initialize the crypto callbacks and logging stuff
   if (!initialized) {
     NR_reg_init(NR_REG_MODE_LOCAL);
     nr_crypto_vtbl = &nr_ice_crypto_nss_vtbl;
     initialized = true;
 
     // Set the priorites for candidate type preferences.
     // These numbers come from RFC 5245 S. 4.1.2.2
@@ -467,29 +472,16 @@ void NrIceCtx::Init(bool allow_loopback,
       NR_reg_set_char((char *)NR_STUN_REG_PREF_ALLOW_LINK_LOCAL_ADDRS, 1);
     }
     if (force_net_interface.Length() > 0) {
       // Stupid cast.... but needed
       const nsCString& flat = PromiseFlatCString(static_cast<nsACString&>(force_net_interface));
       NR_reg_set_string((char *)NR_ICE_REG_PREF_FORCE_INTERFACE_NAME, const_cast<char*>(flat.get()));
     }
   }
-}
-
-RefPtr<NrIceCtx> NrIceCtx::Create(const std::string& name,
-                                  bool offerer,
-                                  bool allow_loopback,
-                                  bool tcp_enabled,
-                                  bool allow_link_local,
-                                  bool hide_non_default,
-                                  Policy policy) {
-   RefPtr<NrIceCtx> ctx = new NrIceCtx(name, offerer, policy);
-
-  // Initialize the crypto callbacks and logging stuff
-  Init(allow_loopback, tcp_enabled, allow_link_local);
 
   // Create the ICE context
   int r;
 
   UINT4 flags = offerer ? NR_ICE_CTX_FLAGS_OFFERER:
       NR_ICE_CTX_FLAGS_ANSWERER;
   flags |= NR_ICE_CTX_FLAGS_AGGRESSIVE_NOMINATION;
   if (policy == ICE_POLICY_RELAY) {
--- a/media/mtransport/nricectx.h
+++ b/media/mtransport/nricectx.h
@@ -210,20 +210,16 @@ class NrIceCtx {
                      ICE_CONTROLLED
   };
 
   enum Policy { ICE_POLICY_NONE,
                 ICE_POLICY_RELAY,
                 ICE_POLICY_ALL
   };
 
-  static void Init(bool allow_loopback = false,
-                   bool tcp_enabled = true,
-                   bool allow_link_local = false);
-
   // TODO(ekr@rtfm.com): Too many bools here. Bug 1193437.
   static RefPtr<NrIceCtx> Create(const std::string& name,
                                  bool offerer,
                                  bool allow_loopback = false,
                                  bool tcp_enabled = true,
                                  bool allow_link_local = false,
                                  bool hide_non_default = false,
                                  Policy policy = ICE_POLICY_ALL);
--- a/media/mtransport/test/TestSyncRunnable.cpp
+++ b/media/mtransport/test/TestSyncRunnable.cpp
@@ -54,8 +54,24 @@ TEST_F(TestSyncRunnable, TestDispatch)
 }
 
 TEST_F(TestSyncRunnable, TestDispatchStatic)
 {
   RefPtr<TestRunnable> r(new TestRunnable());
   SyncRunnable::DispatchToThread(gThread, r);
   ASSERT_TRUE(r->ran());
 }
+
+
+#include "mtransport_test_utils.h"
+MtransportTestUtils *test_utils;
+
+int main(int argc, char **argv)
+{
+  test_utils = new MtransportTestUtils();
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/buffered_stun_socket_unittest.cpp
+++ b/media/mtransport/test/buffered_stun_socket_unittest.cpp
@@ -18,48 +18,47 @@ extern "C" {
 #include "nr_api.h"
 #include "nr_socket.h"
 #include "nr_socket_buffered_stun.h"
 #include "transport_addr.h"
 #include "stun.h"
 }
 
 #include "databuffer.h"
+#include "mtransport_test_utils.h"
 #include "dummysocket.h"
 
 #include "nr_socket_prsock.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
+MtransportTestUtils *test_utils;
 
 static uint8_t kStunMessage[] = {
   0x00, 0x01, 0x00, 0x08, 0x21, 0x12, 0xa4, 0x42,
   0x9b, 0x90, 0xbe, 0x2c, 0xae, 0x1a, 0x0c, 0xa8,
   0xa0, 0xd6, 0x8b, 0x08, 0x80, 0x28, 0x00, 0x04,
   0xdb, 0x35, 0x5f, 0xaa
 };
 static size_t kStunMessageLen = sizeof(kStunMessage);
 
-class BufferedStunSocketTest : public MtransportTest {
+class BufferedStunSocketTest : public ::testing::Test {
  public:
   BufferedStunSocketTest()
-      : MtransportTest(),
-        dummy_(nullptr),
-        test_socket_(nullptr) { }
+      : dummy_(nullptr),
+        test_socket_(nullptr) {}
 
   ~BufferedStunSocketTest() {
     nr_socket_destroy(&test_socket_);
   }
 
   void SetUp() {
-    MtransportTest::SetUp();
-
     RefPtr<DummySocket> dummy(new DummySocket());
 
     int r = nr_socket_buffered_stun_create(
         dummy->get_nr_socket(),
         kStunMessageLen,
         TURN_TCP_FRAMING,
         &test_socket_);
     ASSERT_EQ(0, r);
@@ -291,8 +290,25 @@ TEST_F(BufferedStunSocketTest, TestRecei
   size_t len;
   nr_transport_addr addr;
 
   int r = nr_socket_recvfrom(test_socket_,
                              tmp, kStunMessageLen - 1, &len, 0,
                              &addr);
   ASSERT_EQ(R_BAD_DATA, r);
 }
+
+
+
+int main(int argc, char **argv)
+{
+  test_utils = new MtransportTestUtils();
+  NSS_NoDB_Init(nullptr);
+  NSS_SetDomesticPolicy();
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/gtest_ringbuffer_dumper.h
+++ b/media/mtransport/test/gtest_ringbuffer_dumper.h
@@ -8,18 +8,18 @@
 
 #ifndef gtest_ringbuffer_dumper_h__
 #define gtest_ringbuffer_dumper_h__
 
 #include "mozilla/SyncRunnable.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
+#include "gtest_utils.h"
 
-#include "mtransport_test_utils.h"
 #include "runnable_utils.h"
 #include "rlogringbuffer.h"
 
 using mozilla::RLogRingBuffer;
 using mozilla::WrapRunnable;
 
 namespace test {
 class RingbufferDumper : public ::testing::EmptyTestEventListener {
--- a/media/mtransport/test/gtest_utils.h
+++ b/media/mtransport/test/gtest_utils.h
@@ -31,38 +31,28 @@
  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
  * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
  * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
  * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 // Original author: ekr@rtfm.com
-#ifndef gtest_utils__h__
-#define gtest_utils__h__
+#ifndef gtest_utils_h__
+#define gtest_utils_h__
 
 #include <iostream>
 
 #include "nspr.h"
 #include "prinrval.h"
 #include "prthread.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 
-#include "gtest_ringbuffer_dumper.h"
-#include "mtransport_test_utils.h"
-#include "nss.h"
-#include "ssl.h"
-
-extern "C" {
-#include "registry.h"
-#include "transport_addr.h"
-}
-
 // Wait up to timeout seconds for expression to be true
 #define WAIT(expression, timeout) \
   do { \
     for (PRIntervalTime start = PR_IntervalNow(); !(expression) && \
            ! ((PR_IntervalNow() - start) > PR_MillisecondsToInterval(timeout));) { \
       PR_Sleep(10); \
     } \
   } while(0)
@@ -93,111 +83,9 @@ extern "C" {
   } while(0)
 
 #define ASSERT_EQ_WAIT(expected, actual, timeout) \
   do { \
     WAIT(expected == actual, timeout); \
     ASSERT_EQ(expected, actual); \
   } while(0)
 
-using test::RingbufferDumper;
-
-class MtransportTest : public ::testing::Test {
-public:
-  MtransportTest()
-    : test_utils_(nullptr)
-    , dumper_(nullptr)
-  {
-  }
-
-  void SetUp() override {
-    test_utils_ = new MtransportTestUtils();
-    NSS_NoDB_Init(nullptr);
-    NSS_SetDomesticPolicy();
-
-    NR_reg_init(NR_REG_MODE_LOCAL);
-
-    // Attempt to load env vars used by tests.
-    GetEnvironment("TURN_SERVER_ADDRESS", turn_server_);
-    GetEnvironment("TURN_SERVER_USER", turn_user_);
-    GetEnvironment("TURN_SERVER_PASSWORD", turn_password_);
-    GetEnvironment("STUN_SERVER_ADDRESS", stun_server_address_);
-    GetEnvironment("STUN_SERVER_HOSTNAME", stun_server_hostname_);
-
-    std::string disable_non_local;
-    GetEnvironment("MOZ_DISABLE_NONLOCAL_CONNECTIONS", disable_non_local);
-    std::string upload_dir;
-    GetEnvironment("MOZ_UPLOAD_DIR", upload_dir);
-
-    if ((!disable_non_local.empty() && disable_non_local != "0") ||
-        !upload_dir.empty()) {
-      // We're assuming that MOZ_UPLOAD_DIR is only set on tbpl;
-      // MOZ_DISABLE_NONLOCAL_CONNECTIONS probably should be set when running the
-      // cpp unit-tests, but is not presently.
-      stun_server_address_ = "";
-      stun_server_hostname_ = "";
-      turn_server_ = "";
-    }
-
-    // Some tests are flaky and need to check if they're supposed to run.
-    webrtc_enabled_ = CheckEnvironmentFlag("MOZ_WEBRTC_TESTS");
-
-    ::testing::TestEventListeners& listeners =
-        ::testing::UnitTest::GetInstance()->listeners();
-
-    dumper_ = new RingbufferDumper(test_utils_);
-    listeners.Append(dumper_);
-  }
-
-  void TearDown() override {
-    ::testing::UnitTest::GetInstance()->listeners().Release(dumper_);
-    delete dumper_;
-    delete test_utils_;
-  }
-
-  void GetEnvironment(const char* aVar, std::string& out) {
-    char* value = getenv(aVar);
-    if (value) {
-      out = value;
-    }
-  }
-
-  bool CheckEnvironmentFlag(const char* aVar) {
-    std::string value;
-    GetEnvironment(aVar, value);
-    return value == "1";
-  }
-
-  bool WarnIfTurnNotConfigured() const {
-    bool configured =
-        !turn_server_.empty() &&
-        !turn_user_.empty() &&
-        !turn_password_.empty();
-
-    if (configured) {
-      nr_transport_addr addr;
-      if (nr_str_port_to_transport_addr(turn_server_.c_str(), 3478,
-                                        IPPROTO_UDP, &addr)) {
-        printf("Invalid TURN_SERVER_ADDRESS \"%s\". Only IP numbers supported.\n",
-               turn_server_.c_str());
-        configured = false;
-      }
-    } else {
-      printf(
-        "Set TURN_SERVER_ADDRESS, TURN_SERVER_USER, and TURN_SERVER_PASSWORD\n"
-        "environment variables to run this test\n");
-    }
-
-    return !configured;
-  }
-
-  MtransportTestUtils* test_utils_;
-  RingbufferDumper* dumper_;
-
-  std::string turn_server_;
-  std::string turn_user_;
-  std::string turn_password_;
-  std::string stun_server_address_;
-  std::string stun_server_hostname_;
-
-  bool webrtc_enabled_;
-};
 #endif
--- a/media/mtransport/test/ice_unittest.cpp
+++ b/media/mtransport/test/ice_unittest.cpp
@@ -16,52 +16,54 @@
 
 #include "sigslot.h"
 
 #include "logging.h"
 #include "nspr.h"
 #include "nss.h"
 #include "ssl.h"
 
-#include "mozilla/Preferences.h"
 #include "mozilla/Scoped.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 
 #include "nricectx.h"
 #include "nricemediastream.h"
 #include "nriceresolverfake.h"
 #include "nriceresolver.h"
 #include "nrinterfaceprioritizer.h"
+#include "mtransport_test_utils.h"
 #include "gtest_ringbuffer_dumper.h"
 #include "rlogringbuffer.h"
 #include "runnable_utils.h"
 #include "stunserver.h"
 #include "nr_socket_prsock.h"
 #include "test_nr_socket.h"
 #include "ice_ctx.h"
+// TODO(bcampen@mozilla.com): Big fat hack since the build system doesn't give
+// us a clean way to add object files to a single executable.
+#include "stunserver.cpp"
 #include "stun_udp_socket_filter.h"
 #include "mozilla/net/DNS.h"
 
 #include "ice_ctx.h"
 #include "ice_peer_ctx.h"
 #include "ice_media_stream.h"
 
 extern "C" {
-#include "async_timer.h"
 #include "r_data.h"
 #include "util.h"
 }
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
-
 using namespace mozilla;
+MtransportTestUtils *test_utils;
 
 bool stream_added = false;
 
 static unsigned int kDefaultTimeout = 7000;
 
 //TODO(nils@mozilla.com): This should get replaced with some non-external
 //solution like discussed in bug 860775.
 const std::string kDefaultStunServerHostname(
@@ -70,116 +72,24 @@ const std::string kBogusStunServerHostna
     (char *)"stun-server-nonexistent.invalid");
 const uint16_t kDefaultStunServerPort=3478;
 const std::string kBogusIceCandidate(
     (char *)"candidate:0 2 UDP 2113601790 192.168.178.20 50769 typ");
 
 const std::string kUnreachableHostIceCandidate(
     (char *)"candidate:0 1 UDP 2113601790 192.168.178.20 50769 typ host");
 
+std::string g_stun_server_address;
+std::string g_stun_server_hostname(kDefaultStunServerHostname);
+std::string g_turn_server;
+std::string g_turn_user;
+std::string g_turn_password;
+
 namespace {
 
-// DNS resolution helper code
-static std::string
-Resolve(const std::string& fqdn, int address_family)
-{
-  struct addrinfo hints;
-  memset(&hints, 0, sizeof(hints));
-  hints.ai_family = address_family;
-  hints.ai_protocol = IPPROTO_UDP;
-  struct addrinfo *res;
-  int err = getaddrinfo(fqdn.c_str(), nullptr, &hints, &res);
-  if (err) {
-    std::cerr << "Error in getaddrinfo: " << err << std::endl;
-    return "";
-  }
-
-  char str_addr[64] = {0};
-  switch (res->ai_family) {
-    case AF_INET:
-      inet_ntop(
-          AF_INET,
-          &reinterpret_cast<struct sockaddr_in*>(res->ai_addr)->sin_addr,
-          str_addr,
-          sizeof(str_addr));
-      break;
-    case AF_INET6:
-      inet_ntop(
-          AF_INET6,
-          &reinterpret_cast<struct sockaddr_in6*>(res->ai_addr)->sin6_addr,
-          str_addr,
-          sizeof(str_addr));
-      break;
-    default:
-      std::cerr << "Got unexpected address family in DNS lookup: "
-                << res->ai_family << std::endl;
-      return "";
-  }
-
-  if (!strlen(str_addr)) {
-    std::cerr << "inet_ntop failed" << std::endl;
-  }
-
-  return str_addr;
-}
-
-class StunTest : public MtransportTest {
-public:
-  StunTest() : MtransportTest() {
-    stun_server_hostname_ = kDefaultStunServerHostname;
-  }
-
-  void SetUp() override {
-    MtransportTest::SetUp();
-
-    // If only a STUN server FQDN was provided, look up its IP address for the
-    // address-only tests.
-    if (stun_server_address_.empty() && !stun_server_hostname_.empty()) {
-      stun_server_address_ = Resolve(stun_server_hostname_, AF_INET);
-    }
-
-    RLogRingBuffer::CreateInstance();
-
-    // Make sure NrIceCtx is in a testable state.
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&NrIceCtx::internal_DeinitializeGlobal),
-        NS_DISPATCH_SYNC);
-
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunServer::GetInstance, AF_INET),
-                       NS_DISPATCH_SYNC);
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunServer::GetInstance, AF_INET6),
-                       NS_DISPATCH_SYNC);
-
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
-                       NS_DISPATCH_SYNC);
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
-                       NS_DISPATCH_SYNC);
-  }
-
-  void TearDown() override {
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&NrIceCtx::internal_DeinitializeGlobal),
-        NS_DISPATCH_SYNC);
-
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunServer::ShutdownInstance), NS_DISPATCH_SYNC);
-
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunTcpServer::ShutdownInstance), NS_DISPATCH_SYNC);
-
-    RLogRingBuffer::DestroyInstance();
-
-    MtransportTest::TearDown();
-  }
-};
-
 enum TrickleMode { TRICKLE_NONE, TRICKLE_SIMULATE, TRICKLE_REAL };
 
 const unsigned int ICE_TEST_PEER_OFFERER = (1 << 0);
 const unsigned int ICE_TEST_PEER_ALLOW_LOOPBACK = (1 << 1);
 const unsigned int ICE_TEST_PEER_ENABLED_TCP = (1 << 2);
 const unsigned int ICE_TEST_PEER_ALLOW_LINK_LOCAL = (1 << 3);
 const unsigned int ICE_TEST_PEER_HIDE_NON_DEFAULT = (1 << 4);
 
@@ -303,32 +213,30 @@ class IceCandidatePairCompare {
 };
 
 class IceTestPeer;
 
 class SchedulableTrickleCandidate {
   public:
     SchedulableTrickleCandidate(IceTestPeer *peer,
                                 size_t stream,
-                                const std::string &candidate,
-                                MtransportTestUtils* utils) :
+                                const std::string &candidate) :
       peer_(peer),
       stream_(stream),
       candidate_(candidate),
-      timer_handle_(nullptr),
-      test_utils_(utils) {
+      timer_handle_(nullptr) {
     }
 
     ~SchedulableTrickleCandidate() {
       if (timer_handle_)
         NR_async_timer_cancel(timer_handle_);
     }
 
     void Schedule(unsigned int ms) {
-      test_utils_->sts_target()->Dispatch(
+      test_utils->sts_target()->Dispatch(
           WrapRunnable(this, &SchedulableTrickleCandidate::Schedule_s, ms),
           NS_DISPATCH_SYNC);
     }
 
     void Schedule_s(unsigned int ms) {
       MOZ_ASSERT(!timer_handle_);
       NR_ASYNC_TIMER_SET(ms, Trickle_cb, this, &timer_handle_);
     }
@@ -363,27 +271,25 @@ class SchedulableTrickleCandidate {
       return candidate_.find("typ relay") != std::string::npos;
     }
 
   private:
     IceTestPeer *peer_;
     size_t stream_;
     std::string candidate_;
     void *timer_handle_;
-    MtransportTestUtils* test_utils_;
 
     DISALLOW_COPY_ASSIGN(SchedulableTrickleCandidate);
 };
 
 class IceTestPeer : public sigslot::has_slots<> {
  public:
   // TODO(ekr@rtfm.com): Convert to flags when NrIceCtx::Create() does.
   // Bug 1193437.
-  IceTestPeer(const std::string& name, MtransportTestUtils* utils,
-              bool offerer,
+  IceTestPeer(const std::string& name, bool offerer,
               bool allow_loopback = false, bool enable_tcp = true,
               bool allow_link_local = false, bool hide_non_default = false) :
       name_(name),
       ice_ctx_(NrIceCtx::Create(name, offerer, allow_loopback,
                                 enable_tcp, allow_link_local, hide_non_default)),
       streams_(),
       candidates_(),
       gathering_complete_(false),
@@ -397,32 +303,31 @@ class IceTestPeer : public sigslot::has_
       remote_(nullptr),
       candidate_filter_(nullptr),
       expected_local_type_(NrIceCandidate::ICE_HOST),
       expected_local_transport_(kNrIceTransportUdp),
       expected_remote_type_(NrIceCandidate::ICE_HOST),
       trickle_mode_(TRICKLE_NONE),
       trickled_(0),
       simulate_ice_lite_(false),
-      nat_(new TestNat),
-      test_utils_(utils) {
+      nat_(new TestNat) {
     ice_ctx_->SignalGatheringStateChange.connect(
         this,
         &IceTestPeer::GatheringStateChange);
     ice_ctx_->SignalConnectionStateChange.connect(
         this,
         &IceTestPeer::ConnectionStateChange);
 
     int r = ice_ctx_->SetNat(nat_);
     (void)r;
     MOZ_ASSERT(!r);
   }
 
   ~IceTestPeer() {
-    test_utils_->sts_target()->Dispatch(WrapRunnable(this,
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
                                                     &IceTestPeer::Shutdown),
         NS_DISPATCH_SYNC);
 
     // Give the ICE destruction callback time to fire before
     // we destroy the resolver.
     PR_Sleep(1000);
   }
 
@@ -440,28 +345,28 @@ class IceTestPeer : public sigslot::has_
     stream->SignalCandidate.connect(this, &IceTestPeer::CandidateInitialized);
     stream->SignalReady.connect(this, &IceTestPeer::StreamReady);
     stream->SignalFailed.connect(this, &IceTestPeer::StreamFailed);
     stream->SignalPacketReceived.connect(this, &IceTestPeer::PacketReceived);
   }
 
   void AddStream(int components)
   {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(this, &IceTestPeer::AddStream_s, components),
         NS_DISPATCH_SYNC);
   }
 
   void RemoveStream_s(size_t index) {
     streams_[index] = nullptr;
     ice_ctx_->SetStream(index, nullptr);
   }
 
   void RemoveStream(size_t index) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(this, &IceTestPeer::RemoveStream_s, index),
         NS_DISPATCH_SYNC);
   }
 
   void SetStunServer(const std::string addr, uint16_t port,
                      const char* transport = kNrIceTransportUdp) {
     if (addr.empty()) {
       // Happens when MOZ_DISABLE_NONLOCAL_CONNECTIONS is set
@@ -503,18 +408,18 @@ class IceTestPeer : public sigslot::has_
     turn_servers.push_back(*server);
     ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetTurnServers(turn_servers)));
   }
 
   void SetTurnServers(const std::vector<NrIceTurnServer> servers) {
     ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetTurnServers(servers)));
   }
 
-  void SetFakeResolver(const std::string& ip,
-                       const std::string& fqdn) {
+  void SetFakeResolver(const std::string& ip = g_stun_server_address,
+                       const std::string& fqdn = g_stun_server_hostname) {
     ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
     if (!ip.empty() && !fqdn.empty()) {
       PRNetAddr addr;
       PRStatus status = PR_StringToNetAddr(ip.c_str(), &addr);
       addr.inet.port = kDefaultStunServerPort;
       ASSERT_EQ(PR_SUCCESS, status);
       fake_resolver_.SetAddr(fqdn, addr);
     }
@@ -526,17 +431,17 @@ class IceTestPeer : public sigslot::has_
     ASSERT_TRUE(NS_SUCCEEDED(dns_resolver_->Init()));
     ASSERT_TRUE(NS_SUCCEEDED(ice_ctx_->SetResolver(
         dns_resolver_->AllocateResolver())));
   }
 
   void Gather() {
     nsresult res;
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartGathering),
         NS_DISPATCH_SYNC);
 
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void UseNat() {
     nat_->enabled_ = true;
@@ -565,17 +470,17 @@ class IceTestPeer : public sigslot::has_
     }
     return attrs;
   }
 
   std::vector<std::string> GetCandidates(size_t stream) {
     std::vector<std::string> v;
 
     RUN_ON_THREAD(
-        test_utils_->sts_target(),
+        test_utils->sts_target(),
         WrapRunnableRet(&v, this, &IceTestPeer::GetCandidates_s, stream));
 
     return v;
   }
 
   std::string FilterCandidate(const std::string& candidate) {
     if (candidate_filter_) {
       return candidate_filter_(candidate);
@@ -651,17 +556,17 @@ class IceTestPeer : public sigslot::has_
       EXPECT_TRUE(false) << "No such stream " << stream;
       return false;
     }
     return streams_[stream]->state() == NrIceMediaStream::ICE_OPEN;
   }
   bool is_ready(size_t stream)
   {
     bool result;
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&result, this, &IceTestPeer::is_ready_s, stream),
         NS_DISPATCH_SYNC);
     return result;
   }
   bool ice_complete() { return ice_complete_; }
   bool ice_reached_checking() { return ice_reached_checking_; }
   size_t received() { return received_; }
   size_t sent() { return sent_; }
@@ -710,17 +615,17 @@ class IceTestPeer : public sigslot::has_
       // Now start checks
       res = ice_ctx_->StartChecks();
       ASSERT_TRUE(NS_SUCCEEDED(res));
     }
   }
 
   void Connect(IceTestPeer *remote, TrickleMode trickle_mode,
                bool start = true) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(
             this, &IceTestPeer::Connect_s, remote, trickle_mode, start),
         NS_DISPATCH_SYNC);
   }
 
   void SimulateTrickle(size_t stream) {
     std::cerr << "Doing trickle for stream " << stream << std::endl;
     // If we are in trickle deferred mode, now trickle in the candidates
@@ -745,18 +650,17 @@ class IceTestPeer : public sigslot::has_
   std::vector<SchedulableTrickleCandidate*>& ControlTrickle(size_t stream) {
     std::cerr << "Doing controlled trickle for stream " << stream << std::endl;
 
     std::vector<std::string> candidates =
       remote_->GetCandidates(stream);
 
     for (size_t j=0; j<candidates.size(); j++) {
       controlled_trickle_candidates_[stream].push_back(
-          new SchedulableTrickleCandidate(
-              this, stream, candidates[j], test_utils_));
+          new SchedulableTrickleCandidate(this, stream, candidates[j]));
     }
 
     return controlled_trickle_candidates_[stream];
   }
 
   nsresult TrickleCandidate_s(const std::string &candidate, size_t stream) {
     if (!streams_[stream]) {
       // stream might have gone away before the trickle timer popped
@@ -877,23 +781,23 @@ class IceTestPeer : public sigslot::has_
           delete local;
           delete remote;
         }
       }
     }
   }
 
   void DumpAndCheckActiveCandidates() {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnable(this, &IceTestPeer::DumpAndCheckActiveCandidates_s),
       NS_DISPATCH_SYNC);
   }
 
   void Close() {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnable(ice_ctx_, &NrIceCtx::destroy_peer_ctx),
       NS_DISPATCH_SYNC);
   }
 
   void Shutdown() {
     for (auto s = controlled_trickle_candidates_.begin();
          s != controlled_trickle_candidates_.end();
          ++s) {
@@ -914,17 +818,17 @@ class IceTestPeer : public sigslot::has_
   {
     remote_ = nullptr;
   }
 
   void StartChecks() {
     nsresult res;
 
     // Now start checks
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartChecks),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   // Handle events
   void GatheringStateChange(NrIceCtx* ctx,
                             NrIceCtx::GatheringState state) {
@@ -992,17 +896,17 @@ class IceTestPeer : public sigslot::has_
     }
 
     return streams_[stream_index]->GetCandidatePairs(pairs);
   }
 
   nsresult GetCandidatePairs(size_t stream_index,
                              std::vector<NrIceCandidatePair>* pairs) {
     nsresult v;
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&v, this,
                         &IceTestPeer::GetCandidatePairs_s,
                         stream_index,
                         pairs),
         NS_DISPATCH_SYNC);
     return v;
   }
 
@@ -1177,55 +1081,55 @@ class IceTestPeer : public sigslot::has_
     std::vector<std::string> attributes;
 
     attributes.push_back(candidate);
     streams_[i]->ParseAttributes(attributes);
   }
 
   void ParseCandidate(size_t i, const std::string& candidate)
   {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(this,
                         &IceTestPeer::ParseCandidate_s,
                         i,
                         candidate),
         NS_DISPATCH_SYNC);
   }
 
   void DisableComponent_s(size_t stream, int component_id) {
     ASSERT_LT(stream, streams_.size());
     ASSERT_TRUE(streams_[stream]) << "No such stream " << stream;
     nsresult res = streams_[stream]->DisableComponent(component_id);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void DisableComponent(size_t stream, int component_id)
   {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(this,
                         &IceTestPeer::DisableComponent_s,
                         stream,
                         component_id),
         NS_DISPATCH_SYNC);
   }
 
   int trickled() { return trickled_; }
 
   void SetControlling(NrIceCtx::Controlling controlling) {
     nsresult res;
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&res, ice_ctx_,
                         &NrIceCtx::SetControlling,
                         controlling),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void SetTiebreaker(uint64_t tiebreaker) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(this,
                      &IceTestPeer::SetTiebreaker_s,
                      tiebreaker),
         NS_DISPATCH_SYNC);
   }
 
   void SetTiebreaker_s(uint64_t tiebreaker) {
     ice_ctx_->peer()->tiebreaker = tiebreaker;
@@ -1234,17 +1138,17 @@ class IceTestPeer : public sigslot::has_
   void SimulateIceLite() {
     simulate_ice_lite_ = true;
     SetControlling(NrIceCtx::ICE_CONTROLLED);
   }
 
   nsresult GetDefaultCandidate(unsigned int stream, NrIceCandidate* cand) {
     nsresult rv;
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&rv, this,
                         &IceTestPeer::GetDefaultCandidate_s,
                         stream, cand),
         NS_DISPATCH_SYNC);
 
     return rv;
   }
 
@@ -1273,52 +1177,54 @@ class IceTestPeer : public sigslot::has_
   NrIceCandidate::Type expected_local_type_;
   std::string expected_local_transport_;
   NrIceCandidate::Type expected_remote_type_;
   std::string expected_remote_addr_;
   TrickleMode trickle_mode_;
   int trickled_;
   bool simulate_ice_lite_;
   RefPtr<mozilla::TestNat> nat_;
-  MtransportTestUtils* test_utils_;
 };
 
 void SchedulableTrickleCandidate::Trickle() {
   timer_handle_ = nullptr;
   nsresult res = peer_->TrickleCandidate_s(candidate_, stream_);
   ASSERT_TRUE(NS_SUCCEEDED(res));
 }
 
-class IceGatherTest : public StunTest {
+class IceGatherTest : public ::testing::Test {
  public:
-  void SetUp() override {
-    StunTest::SetUp();
-
-    Preferences::SetInt("media.peerconnection.ice.tcp_so_sock_count", 3);
-
-    test_utils_->sts_target()->Dispatch(
+  void SetUp() {
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(TestStunServer::GetInstance(AF_INET),
                      &TestStunServer::Reset),
         NS_DISPATCH_SYNC);
     if (TestStunServer::GetInstance(AF_INET6)) {
-      test_utils_->sts_target()->Dispatch(
+      test_utils->sts_target()->Dispatch(
           WrapRunnable(TestStunServer::GetInstance(AF_INET6),
                        &TestStunServer::Reset),
           NS_DISPATCH_SYNC);
     }
   }
 
-  void TearDown() override {
+  void TearDown() {
     peer_ = nullptr;
-    StunTest::TearDown();
+
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
+                                                    &IceGatherTest::TearDown_s),
+                                       NS_DISPATCH_SYNC);
+  }
+
+  void TearDown_s() {
+    NrIceCtx::internal_DeinitializeGlobal();
   }
 
   void EnsurePeer(const unsigned int flags = ICE_TEST_PEER_OFFERER) {
     if (!peer_) {
-      peer_ = new IceTestPeer("P1", test_utils_,
+      peer_ = new IceTestPeer("P1",
                               flags & ICE_TEST_PEER_OFFERER,
                               flags & ICE_TEST_PEER_ALLOW_LOOPBACK,
                               flags & ICE_TEST_PEER_ENABLED_TCP,
                               flags & ICE_TEST_PEER_ALLOW_LINK_LOCAL,
                               flags & ICE_TEST_PEER_HIDE_NON_DEFAULT);
       peer_->AddStream(1);
     }
   }
@@ -1449,56 +1355,60 @@ class IceGatherTest : public StunTest {
       std::cerr << "Candidate: " << c << std::endl;
     }
   }
 
  protected:
   mozilla::ScopedDeletePtr<IceTestPeer> peer_;
 };
 
-class IceConnectTest : public StunTest {
+class IceConnectTest : public ::testing::Test {
  public:
   IceConnectTest() :
     initted_(false),
     use_nat_(false),
     filtering_type_(TestNat::ENDPOINT_INDEPENDENT),
     mapping_type_(TestNat::ENDPOINT_INDEPENDENT),
     block_udp_(false) {}
 
-  void SetUp() override {
-    StunTest::SetUp();
-
+  void SetUp() {
     nsresult rv;
     target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
   }
 
-  void TearDown() override {
+  void TearDown() {
     p1_ = nullptr;
     p2_ = nullptr;
 
-    StunTest::TearDown();
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
+                                                    &IceConnectTest::TearDown_s),
+                                       NS_DISPATCH_SYNC);
+  }
+
+  void TearDown_s() {
+    NrIceCtx::internal_DeinitializeGlobal();
   }
 
   void AddStream(const std::string& name, int components) {
     Init(false, false);
     p1_->AddStream(components);
     p2_->AddStream(components);
   }
 
   void RemoveStream(size_t index) {
     p1_->RemoveStream(index);
     p2_->RemoveStream(index);
   }
 
   void Init(bool allow_loopback, bool enable_tcp, bool default_only = false) {
     if (!initted_) {
-      p1_ = new IceTestPeer("P1", test_utils_, true, allow_loopback,
+      p1_ = new IceTestPeer("P1", true, allow_loopback,
                             enable_tcp, false, default_only);
-      p2_ = new IceTestPeer("P2", test_utils_, false, allow_loopback,
+      p2_ = new IceTestPeer("P2", false, allow_loopback,
                             enable_tcp, false, default_only);
     }
     initted_ = true;
   }
 
   bool Gather(unsigned int waitTime = kDefaultTimeout,
               bool setupStunServers = true) {
     Init(false, false);
@@ -1516,19 +1426,19 @@ class IceConnectTest : public StunTest {
       p2_->SetFilteringType(filtering_type_);
       p1_->SetMappingType(mapping_type_);
       p2_->SetMappingType(mapping_type_);
       p1_->SetBlockUdp(block_udp_);
       p2_->SetBlockUdp(block_udp_);
     } else if (setupStunServers) {
       std::vector<NrIceStunServer> stun_servers;
 
-      stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
+      stun_servers.push_back(*NrIceStunServer::Create(g_stun_server_address,
                                                       kDefaultStunServerPort, kNrIceTransportUdp));
-      stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
+      stun_servers.push_back(*NrIceStunServer::Create(g_stun_server_address,
                                                       kDefaultStunServerPort, kNrIceTransportTcp));
 
       p1_->SetStunServers(stun_servers);
       p2_->SetStunServers(stun_servers);
     }
 
     p1_->Gather();
     p2_->Gather();
@@ -1671,28 +1581,28 @@ class IceConnectTest : public StunTest {
 
   void CloseP1() {
     p1_->Close();
   }
 
   void ConnectThenDelete() {
     p2_->Connect(p1_, TRICKLE_NONE, false);
     p1_->Connect(p2_, TRICKLE_NONE, true);
-    test_utils_->sts_target()->Dispatch(WrapRunnable(this,
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
                                                     &IceConnectTest::CloseP1),
                                        NS_DISPATCH_SYNC);
     p2_->StartChecks();
 
     // Wait to see if we crash
     PR_Sleep(PR_MillisecondsToInterval(kDefaultTimeout));
   }
 
   void SendReceive() {
     //    p1_->Send(2);
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnable(p1_.get(),
                      &IceTestPeer::SendPacket, 0, 1,
                      reinterpret_cast<const unsigned char *>("TEST"), 4),
         NS_DISPATCH_SYNC);
     ASSERT_EQ(1u, p1_->sent());
     ASSERT_TRUE_WAIT(p2_->received() == 1, 1000);
   }
 
@@ -1702,17 +1612,17 @@ class IceConnectTest : public StunTest {
   mozilla::ScopedDeletePtr<IceTestPeer> p1_;
   mozilla::ScopedDeletePtr<IceTestPeer> p2_;
   bool use_nat_;
   TestNat::NatBehavior filtering_type_;
   TestNat::NatBehavior mapping_type_;
   bool block_udp_;
 };
 
-class PrioritizerTest : public StunTest {
+class PrioritizerTest : public ::testing::Test {
  public:
   PrioritizerTest():
     prioritizer_(nullptr) {}
 
   ~PrioritizerTest() {
     if (prioritizer_) {
       nr_interface_prioritizer_destroy(&prioritizer_);
     }
@@ -1750,36 +1660,33 @@ class PrioritizerTest : public StunTest 
     ASSERT_EQ(0, r);
     ASSERT_LE(pref1, pref2);
   }
 
  private:
   nr_interface_prioritizer *prioritizer_;
 };
 
-class PacketFilterTest : public StunTest {
+class PacketFilterTest : public ::testing::Test {
  public:
   PacketFilterTest(): filter_(nullptr) {}
 
   void SetUp() {
-    StunTest::SetUp();
-
     // Set up enough of the ICE ctx to allow the packet filter to work
     ice_ctx_ = NrIceCtx::Create("test", true);
 
     nsCOMPtr<nsIUDPSocketFilterHandler> handler =
       do_GetService(NS_STUN_UDP_SOCKET_FILTER_HANDLER_CONTRACTID);
     handler->NewFilter(getter_AddRefs(filter_));
   }
 
   void TearDown() {
-    test_utils_->sts_target()->Dispatch(WrapRunnable(this,
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
                                                     &PacketFilterTest::TearDown_s),
                                        NS_DISPATCH_SYNC);
-    StunTest::TearDown();
   }
 
   void TearDown_s() {
     ice_ctx_ = nullptr;
   }
 
   void TestIncoming(const uint8_t* data, uint32_t len,
                     uint8_t from_addr, int from_port,
@@ -1816,165 +1723,165 @@ class PacketFilterTest : public StunTest
   }
 
   nsCOMPtr<nsIUDPSocketFilter> filter_;
   RefPtr<NrIceCtx> ice_ctx_;
 };
 }  // end namespace
 
 TEST_F(IceGatherTest, TestGatherFakeStunServerHostnameNoResolver) {
-  if (stun_server_hostname_.empty()) {
+  if (g_stun_server_hostname.empty()) {
     return;
   }
 
   EnsurePeer();
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
   Gather();
 }
 
 TEST_F(IceGatherTest, TestGatherFakeStunServerTcpHostnameNoResolver) {
-  if (stun_server_hostname_.empty()) {
+  if (g_stun_server_hostname.empty()) {
     return;
   }
 
   EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort,
     kNrIceTransportTcp);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
 TEST_F(IceGatherTest, TestGatherFakeStunServerIpAddress) {
-  if (stun_server_address_.empty()) {
+  if (g_stun_server_address.empty()) {
     return;
   }
 
   EnsurePeer();
-  peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
-  peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
+  peer_->SetStunServer(g_stun_server_address, kDefaultStunServerPort);
+  peer_->SetFakeResolver();
   Gather();
 }
 
 TEST_F(IceGatherTest, TestGatherStunServerIpAddressDefaultRouteOnly) {
-  if (stun_server_address_.empty()) {
+  if (g_stun_server_address.empty()) {
     return;
   }
 
-  peer_ = new IceTestPeer("P1", test_utils_, true, false, false, false, true);
+  peer_ = new IceTestPeer("P1", true, false, false, false, true);
   peer_->AddStream(1);
-  peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
-  peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
+  peer_->SetStunServer(g_stun_server_address, kDefaultStunServerPort);
+  peer_->SetFakeResolver();
   Gather();
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " host "));
 }
 
 TEST_F(IceGatherTest, TestGatherFakeStunServerHostname) {
-  if (stun_server_hostname_.empty()) {
+  if (g_stun_server_hostname.empty()) {
     return;
   }
 
   EnsurePeer();
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
-  peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
+  peer_->SetFakeResolver();
   Gather();
 }
 
 TEST_F(IceGatherTest, TestGatherFakeStunBogusHostname) {
   EnsurePeer();
   peer_->SetStunServer(kBogusStunServerHostname, kDefaultStunServerPort);
-  peer_->SetFakeResolver(stun_server_address_, stun_server_hostname_);
+  peer_->SetFakeResolver();
   Gather();
 }
 
 TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddress) {
-  if (stun_server_address_.empty()) {
+  if (g_stun_server_address.empty()) {
     return;
   }
 
   EnsurePeer();
-  peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort);
+  peer_->SetStunServer(g_stun_server_address, kDefaultStunServerPort);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
 }
 
 TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddressTcp) {
-  if (stun_server_address_.empty()) {
+  if (g_stun_server_address.empty()) {
     return;
   }
 
   EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
-  peer_->SetStunServer(stun_server_address_, kDefaultStunServerPort,
+  peer_->SetStunServer(g_stun_server_address, kDefaultStunServerPort,
     kNrIceTransportTcp);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype so", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
 }
 
 TEST_F(IceGatherTest, TestGatherDNSStunServerHostname) {
-  if (stun_server_hostname_.empty()) {
+  if (g_stun_server_hostname.empty()) {
     return;
   }
 
   EnsurePeer();
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "typ srflx raddr"));
 }
 
 TEST_F(IceGatherTest, TestGatherDNSStunServerHostnameTcp) {
   EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort,
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort,
     kNrIceTransportTcp);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype passive"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype passive", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype so"));
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "tcptype so", " 9 "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "tcptype active", " 9 "));
 }
 
 TEST_F(IceGatherTest, TestGatherDNSStunServerHostnameBothUdpTcp) {
-  if (stun_server_hostname_.empty()) {
+  if (g_stun_server_hostname.empty()) {
     return;
   }
 
   std::vector<NrIceStunServer> stun_servers;
 
   EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
-  stun_servers.push_back(*NrIceStunServer::Create(stun_server_hostname_,
+  stun_servers.push_back(*NrIceStunServer::Create(g_stun_server_hostname,
     kDefaultStunServerPort, kNrIceTransportUdp));
-  stun_servers.push_back(*NrIceStunServer::Create(stun_server_hostname_,
+  stun_servers.push_back(*NrIceStunServer::Create(g_stun_server_hostname,
     kDefaultStunServerPort, kNrIceTransportTcp));
   peer_->SetStunServers(stun_servers);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
 TEST_F(IceGatherTest, TestGatherDNSStunServerIpAddressBothUdpTcp) {
-  if (stun_server_address_.empty()) {
+  if (g_stun_server_address.empty()) {
     return;
   }
 
   std::vector<NrIceStunServer> stun_servers;
 
   EnsurePeer(ICE_TEST_PEER_OFFERER | ICE_TEST_PEER_ENABLED_TCP);
-  stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
+  stun_servers.push_back(*NrIceStunServer::Create(g_stun_server_address,
     kDefaultStunServerPort, kNrIceTransportUdp));
-  stun_servers.push_back(*NrIceStunServer::Create(stun_server_address_,
+  stun_servers.push_back(*NrIceStunServer::Create(g_stun_server_address,
     kDefaultStunServerPort, kNrIceTransportTcp));
   peer_->SetStunServers(stun_servers);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
@@ -1992,47 +1899,47 @@ TEST_F(IceGatherTest, TestGatherDNSStunB
     kNrIceTransportTcp);
   peer_->SetDNSResolver();
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " TCP "));
 }
 
 TEST_F(IceGatherTest, TestDefaultCandidate) {
   EnsurePeer();
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
   Gather();
   NrIceCandidate default_candidate;
   ASSERT_TRUE(NS_SUCCEEDED(peer_->GetDefaultCandidate(0, &default_candidate)));
 }
 
 TEST_F(IceGatherTest, TestGatherTurn) {
   EnsurePeer();
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
-  peer_->SetTurnServer(turn_server_, kDefaultStunServerPort,
-                       turn_user_, turn_password_, kNrIceTransportUdp);
+  peer_->SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                       g_turn_user, g_turn_password, kNrIceTransportUdp);
   Gather();
 }
 
 TEST_F(IceGatherTest, TestGatherTurnTcp) {
   EnsurePeer();
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
-  peer_->SetTurnServer(turn_server_, kDefaultStunServerPort,
-                       turn_user_, turn_password_, kNrIceTransportTcp);
+  peer_->SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                       g_turn_user, g_turn_password, kNrIceTransportTcp);
   Gather();
 }
 
 TEST_F(IceGatherTest, TestGatherDisableComponent) {
-  if (stun_server_hostname_.empty()) {
+  if (g_stun_server_hostname.empty()) {
     return;
   }
 
   EnsurePeer();
-  peer_->SetStunServer(stun_server_hostname_, kDefaultStunServerPort);
+  peer_->SetStunServer(g_stun_server_hostname, kDefaultStunServerPort);
   peer_->AddStream(2);
   peer_->DisableComponent(1, 2);
   Gather();
   std::vector<std::string> candidates =
     peer_->GetCandidates(1);
 
   for (size_t i=0; i<candidates.size(); ++i) {
     size_t sp1 = candidates[i].find(' ');
@@ -2042,25 +1949,25 @@ TEST_F(IceGatherTest, TestGatherDisableC
 
 TEST_F(IceGatherTest, TestGatherVerifyNoLoopback) {
   Gather();
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "127.0.0.1"));
 }
 
 TEST_F(IceGatherTest, TestGatherAllowLoopback) {
   // Set up peer with loopback allowed.
-  peer_ = new IceTestPeer("P1", test_utils_, true, true);
+  peer_ = new IceTestPeer("P1", true, true);
   peer_->AddStream(1);
   Gather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "127.0.0.1"));
 }
 
 TEST_F(IceGatherTest, TestGatherTcpDisabled) {
   // Set up peer with tcp disabled.
-  peer_ = new IceTestPeer("P1", test_utils_, true, false, false);
+  peer_ = new IceTestPeer("P1", true, false, false);
   peer_->AddStream(1);
   Gather();
   ASSERT_FALSE(StreamHasMatchingCandidate(0, " TCP "));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, " UDP "));
 }
 
 // Verify that a bogus candidate doesn't cause crashes on the
 // main thread. See bug 856433.
@@ -2153,17 +2060,17 @@ TEST_F(IceGatherTest, TestStunServerTric
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "192.0.2.1"));
   WaitForGather();
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "192.0.2.1"));
 }
 
 // Test default route only with our fake STUN server and
 // apparently NATted.
 TEST_F(IceGatherTest, TestFakeStunServerNatedDefaultRouteOnly) {
-  peer_ = new IceTestPeer("P1", test_utils_, true, false, false, false, true);
+  peer_ = new IceTestPeer("P1", true, false, false, false, true);
   peer_->AddStream(1);
   UseFakeStunUdpServerWithResponse("192.0.2.1", 3333);
   Gather(0);
   WaitForGather();
   DumpCandidates(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
   NrIceCandidate default_candidate;
@@ -2171,17 +2078,17 @@ TEST_F(IceGatherTest, TestFakeStunServer
   if (NS_SUCCEEDED(rv)) {
     ASSERT_NE(NrIceCandidate::ICE_HOST, default_candidate.type);
   }
 }
 
 // Test default route only with our fake STUN server and
 // apparently non-NATted.
 TEST_F(IceGatherTest, TestFakeStunServerNoNatDefaultRouteOnly) {
-  peer_ = new IceTestPeer("P1", test_utils_, true, false, false, false, true);
+  peer_ = new IceTestPeer("P1", true, false, false, false, true);
   peer_->AddStream(1);
   UseTestStunServer();
   Gather(0);
   WaitForGather();
   DumpCandidates(0);
   ASSERT_FALSE(StreamHasMatchingCandidate(0, "host"));
   ASSERT_TRUE(StreamHasMatchingCandidate(0, "srflx"));
 }
@@ -2434,70 +2341,70 @@ TEST_F(IceConnectTest, TestGatherSymmetr
   AddStream("first", 1);
   UseNat();
   SetFilteringType(TestNat::PORT_DEPENDENT);
   SetMappingType(TestNat::PORT_DEPENDENT);
   ASSERT_TRUE(Gather());
 }
 
 TEST_F(IceConnectTest, TestConnectSymmetricNat) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
   UseNat();
   SetFilteringType(TestNat::PORT_DEPENDENT);
   SetMappingType(TestNat::PORT_DEPENDENT);
   p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED);
   p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(IceConnectTest, TestGatherNatBlocksUDP) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
   UseNat();
   BlockUdp();
   std::vector<NrIceTurnServer> turn_servers;
-  std::vector<unsigned char> password_vec(turn_password_.begin(),
-                                          turn_password_.end());
+  std::vector<unsigned char> password_vec(g_turn_password.begin(),
+                                          g_turn_password.end());
   turn_servers.push_back(
-      *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
-                               turn_user_, password_vec, kNrIceTransportTcp));
+      *NrIceTurnServer::Create(g_turn_server, kDefaultStunServerPort,
+                               g_turn_user, password_vec, kNrIceTransportTcp));
   turn_servers.push_back(
-      *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
-                               turn_user_, password_vec, kNrIceTransportUdp));
+      *NrIceTurnServer::Create(g_turn_server, kDefaultStunServerPort,
+                               g_turn_user, password_vec, kNrIceTransportUdp));
   SetTurnServers(turn_servers);
   // We have to wait for the UDP-based stuff to time out.
   ASSERT_TRUE(Gather(kDefaultTimeout * 3));
 }
 
 TEST_F(IceConnectTest, TestConnectNatBlocksUDP) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
   UseNat();
   BlockUdp();
   std::vector<NrIceTurnServer> turn_servers;
-  std::vector<unsigned char> password_vec(turn_password_.begin(),
-                                          turn_password_.end());
+  std::vector<unsigned char> password_vec(g_turn_password.begin(),
+                                          g_turn_password.end());
   turn_servers.push_back(
-      *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
-                               turn_user_, password_vec, kNrIceTransportTcp));
+      *NrIceTurnServer::Create(g_turn_server, kDefaultStunServerPort,
+                               g_turn_user, password_vec, kNrIceTransportTcp));
   turn_servers.push_back(
-      *NrIceTurnServer::Create(turn_server_, kDefaultStunServerPort,
-                               turn_user_, password_vec, kNrIceTransportUdp));
+      *NrIceTurnServer::Create(g_turn_server, kDefaultStunServerPort,
+                               g_turn_user, password_vec, kNrIceTransportUdp));
   SetTurnServers(turn_servers);
   p1_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED,
                         kNrIceTransportTcp);
   p2_->SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                         NrIceCandidate::Type::ICE_RELAYED,
                         kNrIceTransportTcp);
   ASSERT_TRUE(Gather(kDefaultTimeout * 3));
@@ -2605,41 +2512,36 @@ void DelayRelayCandidates(
     } else {
       (*i)->Schedule(0);
     }
   }
 }
 
 void AddNonPairableCandidates(
     std::vector<SchedulableTrickleCandidate*>& candidates,
-    IceTestPeer *peer, size_t stream, int net_type,
-    MtransportTestUtils* test_utils_) {
+    IceTestPeer *peer, size_t stream, int net_type) {
   for (int i=1; i<5; i++) {
     if (net_type == i)
       continue;
     switch (i) {
       case 1:
         candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
-                   "candidate:0 1 UDP 2113601790 10.0.0.1 12345 typ host",
-                   test_utils_));
+                   "candidate:0 1 UDP 2113601790 10.0.0.1 12345 typ host"));
         break;
       case 2:
         candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
-                   "candidate:0 1 UDP 2113601791 172.16.1.1 12345 typ host",
-                   test_utils_));
+                   "candidate:0 1 UDP 2113601791 172.16.1.1 12345 typ host"));
         break;
       case 3:
         candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
-                   "candidate:0 1 UDP 2113601792 192.168.0.1 12345 typ host",
-                   test_utils_));
+                   "candidate:0 1 UDP 2113601792 192.168.0.1 12345 typ host"));
         break;
       case 4:
         candidates.push_back(new SchedulableTrickleCandidate(peer, stream,
-                   "candidate:0 1 UDP 2113601793 100.64.1.1 12345 typ host",
-                   test_utils_));
+                   "candidate:0 1 UDP 2113601793 100.64.1.1 12345 typ host"));
         break;
       default:
         UNIMPLEMENTED;
     }
   }
 
   for (auto i = candidates.rbegin(); i != candidates.rend(); ++i) {
     std::cerr << "Scheduling candidate: " << (*i)->Candidate().c_str() << std::endl;
@@ -2819,180 +2721,180 @@ TEST_F(IceConnectTest, DISABLED_TestSend
   SetCandidateFilter(IsTcpSoCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_HOST,
     NrIceCandidate::Type::ICE_HOST, kNrIceTransportTcp);
   Connect();
   SendReceive();
 }
 
 TEST_F(IceConnectTest, TestConnectTurn) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnWithDelay) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
   p1_->Gather();
   PR_Sleep(500);
   p2_->Gather();
   ConnectTrickle(TRICKLE_REAL);
   WaitForGather();
   WaitForComplete();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnWithNormalTrickleDelay) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   RealisticTrickleDelay(p2_->ControlTrickle(0));
 
   ASSERT_TRUE_WAIT(p1_->ice_complete(), kDefaultTimeout);
   ASSERT_TRUE_WAIT(p2_->ice_complete(), kDefaultTimeout);
   AssertCheckingReached();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnWithNormalTrickleDelayOneSided) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   RealisticTrickleDelay(p1_->ControlTrickle(0));
   p2_->SimulateTrickle(0);
 
   ASSERT_TRUE_WAIT(p1_->ice_complete(), kDefaultTimeout);
   ASSERT_TRUE_WAIT(p2_->ice_complete(), kDefaultTimeout);
   AssertCheckingReached();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnWithLargeTrickleDelay) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   SetCandidateFilter(SabotageHostCandidateAndDropReflexive);
   ASSERT_TRUE(Gather());
   ConnectTrickle();
   // Trickle host candidates immediately, but delay relay candidates
   DelayRelayCandidates(p1_->ControlTrickle(0), 3700);
   DelayRelayCandidates(p2_->ControlTrickle(0), 3700);
 
   ASSERT_TRUE_WAIT(p1_->ice_complete(), kDefaultTimeout);
   ASSERT_TRUE_WAIT(p2_->ice_complete(), kDefaultTimeout);
   AssertCheckingReached();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnTcp) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_, kNrIceTransportTcp);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password, kNrIceTransportTcp);
   ASSERT_TRUE(Gather());
   Connect();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnOnly) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED);
   Connect();
 }
 
 TEST_F(IceConnectTest, TestConnectTurnTcpOnly) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_, kNrIceTransportTcp);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password, kNrIceTransportTcp);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED,
                    kNrIceTransportTcp);
   Connect();
 }
 
 TEST_F(IceConnectTest, TestSendReceiveTurnOnly) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED);
   Connect();
   SendReceive();
 }
 
 TEST_F(IceConnectTest, TestSendReceiveTurnTcpOnly) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
-  SetTurnServer(turn_server_, kDefaultStunServerPort,
-                turn_user_, turn_password_, kNrIceTransportTcp);
+  SetTurnServer(g_turn_server, kDefaultStunServerPort,
+                g_turn_user, g_turn_password, kNrIceTransportTcp);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED,
                    kNrIceTransportTcp);
   Connect();
   SendReceive();
 }
 
 TEST_F(IceConnectTest, TestSendReceiveTurnBothOnly) {
-  if (turn_server_.empty())
+  if (g_turn_server.empty())
     return;
 
   AddStream("first", 1);
   std::vector<NrIceTurnServer> turn_servers;
-  std::vector<unsigned char> password_vec(turn_password_.begin(),
-                                          turn_password_.end());
+  std::vector<unsigned char> password_vec(g_turn_password.begin(),
+                                          g_turn_password.end());
   turn_servers.push_back(*NrIceTurnServer::Create(
-                           turn_server_, kDefaultStunServerPort,
-                           turn_user_, password_vec, kNrIceTransportTcp));
+                           g_turn_server, kDefaultStunServerPort,
+                           g_turn_user, password_vec, kNrIceTransportTcp));
   turn_servers.push_back(*NrIceTurnServer::Create(
-                           turn_server_, kDefaultStunServerPort,
-                           turn_user_, password_vec, kNrIceTransportUdp));
+                           g_turn_server, kDefaultStunServerPort,
+                           g_turn_user, password_vec, kNrIceTransportUdp));
   SetTurnServers(turn_servers);
   ASSERT_TRUE(Gather());
   SetCandidateFilter(IsRelayCandidate);
   // UDP is preferred.
   SetExpectedTypes(NrIceCandidate::Type::ICE_RELAYED,
                    NrIceCandidate::Type::ICE_RELAYED,
                    kNrIceTransportUdp);
   Connect();
@@ -3050,36 +2952,34 @@ TEST_F(IceConnectTest, TestHostCandPairi
 
   int host_net = p1_->GetCandidatesPrivateIpv4Range(0);
   if (host_net <= 0) {
     // TODO bug 1226838: make this work with multiple private IPs
     FAIL() << "This test needs exactly one private IPv4 host candidate to work" << std::endl;
   }
 
   ConnectTrickle();
-  AddNonPairableCandidates(p1_->ControlTrickle(0), p1_, 0, host_net,
-                           test_utils_);
-  AddNonPairableCandidates(p2_->ControlTrickle(0), p2_, 0, host_net,
-                           test_utils_);
+  AddNonPairableCandidates(p1_->ControlTrickle(0), p1_, 0, host_net);
+  AddNonPairableCandidates(p2_->ControlTrickle(0), p2_, 0, host_net);
 
   std::vector<NrIceCandidatePair> pairs;
   p1_->GetCandidatePairs(0, &pairs);
   for (auto p : pairs) {
     std::cerr << "Verifying pair:" << std::endl;
     p1_->DumpCandidatePair(p);
     nr_transport_addr addr;
     nr_str_port_to_transport_addr(p.local.local_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
     ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == host_net);
     nr_str_port_to_transport_addr(p.remote.cand_addr.host.c_str(), 0, IPPROTO_UDP, &addr);
     ASSERT_TRUE(nr_transport_addr_get_private_addr_range(&addr) == host_net);
   }
 }
 
 TEST_F(IceConnectTest, TestSrflxCandPairingFilter) {
-  if (stun_server_address_.empty()) {
+  if (g_stun_server_address.empty()) {
     return;
   }
 
   AddStream("first", 1);
   ASSERT_TRUE(Gather(kDefaultTimeout));
   SetCandidateFilter(IsSrflxCandidate);
 
   if (p1_->GetCandidatesPrivateIpv4Range(0) <= 0) {
@@ -3328,8 +3228,146 @@ TEST(InternalsTest, TestAddBogusAttribut
   ASSERT_EQ(0, nr_stun_message_create(&req));
   Data *data;
   ASSERT_EQ(0, r_data_alloc(&data, 3000));
   memset(data->data, 'A', data->len);
   ASSERT_TRUE(nr_stun_message_add_message_integrity_attribute(req, data));
   ASSERT_EQ(0, r_data_destroy(&data));
   ASSERT_EQ(0, nr_stun_message_destroy(&req));
 }
+
+static std::string get_environment(const char *name) {
+  char *value = getenv(name);
+
+  if (!value)
+    return "";
+
+  return value;
+}
+
+// DNS resolution helper code
+static std::string
+Resolve(const std::string& fqdn, int address_family)
+{
+  struct addrinfo hints;
+  memset(&hints, 0, sizeof(hints));
+  hints.ai_family = address_family;
+  hints.ai_protocol = IPPROTO_UDP;
+  struct addrinfo *res;
+  int err = getaddrinfo(fqdn.c_str(), nullptr, &hints, &res);
+  if (err) {
+    std::cerr << "Error in getaddrinfo: " << err << std::endl;
+    return "";
+  }
+
+  char str_addr[64] = {0};
+  switch (res->ai_family) {
+    case AF_INET:
+      inet_ntop(
+          AF_INET,
+          &reinterpret_cast<struct sockaddr_in*>(res->ai_addr)->sin_addr,
+          str_addr,
+          sizeof(str_addr));
+      break;
+    case AF_INET6:
+      inet_ntop(
+          AF_INET6,
+          &reinterpret_cast<struct sockaddr_in6*>(res->ai_addr)->sin6_addr,
+          str_addr,
+          sizeof(str_addr));
+      break;
+    default:
+      std::cerr << "Got unexpected address family in DNS lookup: "
+                << res->ai_family << std::endl;
+      return "";
+  }
+
+  if (!strlen(str_addr)) {
+    std::cerr << "inet_ntop failed" << std::endl;
+  }
+
+  return str_addr;
+}
+
+int main(int argc, char **argv)
+{
+#ifdef ANDROID
+  // This test can cause intermittent oranges on the builders on Linux
+  CHECK_ENVIRONMENT_FLAG("MOZ_WEBRTC_TESTS")
+#endif
+
+  g_turn_server = get_environment("TURN_SERVER_ADDRESS");
+  g_turn_user = get_environment("TURN_SERVER_USER");
+  g_turn_password = get_environment("TURN_SERVER_PASSWORD");
+
+
+  if (g_turn_server.empty() ||
+      g_turn_user.empty(),
+      g_turn_password.empty()) {
+    printf(
+        "Set TURN_SERVER_ADDRESS, TURN_SERVER_USER, and TURN_SERVER_PASSWORD\n"
+        "environment variables to run this test\n");
+    g_turn_server="";
+  }
+
+  std::string tmp = get_environment("STUN_SERVER_ADDRESS");
+  if (tmp != "")
+    g_stun_server_address = tmp;
+
+
+  tmp = get_environment("STUN_SERVER_HOSTNAME");
+  if (tmp != "")
+    g_stun_server_hostname = tmp;
+
+  tmp = get_environment("MOZ_DISABLE_NONLOCAL_CONNECTIONS");
+
+  if ((tmp != "" && tmp != "0") || getenv("MOZ_UPLOAD_DIR")) {
+    // We're assuming that MOZ_UPLOAD_DIR is only set on tbpl;
+    // MOZ_DISABLE_NONLOCAL_CONNECTIONS probably should be set when running the
+    // cpp unit-tests, but is not presently.
+    g_stun_server_address = "";
+    g_stun_server_hostname = "";
+    g_turn_server = "";
+  }
+
+  test_utils = new MtransportTestUtils();
+  NSS_NoDB_Init(nullptr);
+  NSS_SetDomesticPolicy();
+
+  // If only a STUN server FQDN was provided, look up its IP address for the
+  // address-only tests.
+  if (g_stun_server_address.empty() && !g_stun_server_hostname.empty()) {
+    g_stun_server_address = Resolve(g_stun_server_hostname, AF_INET);
+  }
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  ::testing::TestEventListeners& listeners =
+        ::testing::UnitTest::GetInstance()->listeners();
+  // Adds a listener to the end.  Google Test takes the ownership.
+
+  listeners.Append(new test::RingbufferDumper(test_utils));
+  test_utils->sts_target()->Dispatch(
+      WrapRunnableNM(&TestStunServer::GetInstance, AF_INET),
+                     NS_DISPATCH_SYNC);
+  test_utils->sts_target()->Dispatch(
+    WrapRunnableNM(&TestStunServer::GetInstance, AF_INET6),
+                   NS_DISPATCH_SYNC);
+
+  test_utils->sts_target()->Dispatch(
+      WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
+                     NS_DISPATCH_SYNC);
+  test_utils->sts_target()->Dispatch(
+    WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
+                   NS_DISPATCH_SYNC);
+
+  int rv = RUN_ALL_TESTS();
+
+  test_utils->sts_target()->Dispatch(
+    WrapRunnableNM(&TestStunServer::ShutdownInstance), NS_DISPATCH_SYNC);
+
+  test_utils->sts_target()->Dispatch(
+    WrapRunnableNM(&TestStunTcpServer::ShutdownInstance), NS_DISPATCH_SYNC);
+
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/moz.build
+++ b/media/mtransport/test/moz.build
@@ -1,55 +1,59 @@
 # -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
 # vim: set filetype=python:
 # 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/.
 
 if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
-    SOURCES += [
-        'buffered_stun_socket_unittest.cpp',
-        'ice_unittest.cpp',
-        'multi_tcp_socket_unittest.cpp',
-        'nrappkit_unittest.cpp',
-        'proxy_tunnel_socket_unittest.cpp',
-        'rlogringbuffer_unittest.cpp',
-        'runnable_utils_unittest.cpp',
-        'simpletokenbucket_unittest.cpp',
-        'sockettransportservice_unittest.cpp',
-        'stunserver.cpp',
-        'test_nr_socket_unittest.cpp',
-        'TestSyncRunnable.cpp',
-        'transport_unittests.cpp',
-        'turn_unittest.cpp',
-    ]
+    CppUnitTests([
+        'buffered_stun_socket_unittest',
+        'ice_unittest',
+        'multi_tcp_socket_unittest',
+        'nrappkit_unittest',
+        'proxy_tunnel_socket_unittest',
+        'rlogringbuffer_unittest',
+        'runnable_utils_unittest',
+        'simpletokenbucket_unittest',
+        'sockettransportservice_unittest',
+        'test_nr_socket_unittest',
+        'TestSyncRunnable',
+        'transport_unittests',
+        'turn_unittest',
+    ])
 
     if CONFIG['MOZ_SCTP']:
-        SOURCES += [
-            'sctp_unittest.cpp',
-        ]
+        CppUnitTests([
+            'sctp_unittest',
+        ])
 
-
-for var in ('HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR', 'SCTP_DEBUG', 'INET'):
+for var in ('MOZILLA_INTERNAL_API', 'MOZILLA_XPCOMRT_API', 'MOZILLA_EXTERNAL_LINKAGE', 'HAVE_STRDUP', 'NR_SOCKET_IS_VOID_PTR', 'SCTP_DEBUG', 'INET'):
     DEFINES[var] = True
 
 if CONFIG['OS_TARGET'] == 'Android':
     DEFINES['LINUX'] = True
     DEFINES['ANDROID'] = True
     LOCAL_INCLUDES += [
         '/media/mtransport/third_party/nrappkit/src/port/android/include',
     ]
 else:
     DEFINES['INET6'] = True
 
 if CONFIG['OS_TARGET'] == 'Linux':
     DEFINES['LINUX'] = True
     LOCAL_INCLUDES += [
         '/media/mtransport/third_party/nrappkit/src/port/linux/include',
     ]
+    USE_LIBS += [
+        'nspr',
+    ]
+    OS_LIBS += [
+        '-lrt',
+    ]
 
 if CONFIG['OS_TARGET'] == 'Darwin':
     LOCAL_INCLUDES += [
         '/media/mtransport/third_party/nrappkit/src/port/darwin/include',
     ]
 
 if CONFIG['OS_TARGET'] in ('DragonFly', 'FreeBSD', 'NetBSD', 'OpenBSD'):
     if CONFIG['OS_TARGET'] == 'Darwin':
@@ -85,13 +89,40 @@ LOCAL_INCLUDES += [
     '/media/mtransport/third_party/nrappkit/src/log',
     '/media/mtransport/third_party/nrappkit/src/plugin',
     '/media/mtransport/third_party/nrappkit/src/port/generic/include',
     '/media/mtransport/third_party/nrappkit/src/registry',
     '/media/mtransport/third_party/nrappkit/src/share',
     '/media/mtransport/third_party/nrappkit/src/stats',
     '/media/mtransport/third_party/nrappkit/src/util/',
     '/media/mtransport/third_party/nrappkit/src/util/libekr',
+    '/media/webrtc/trunk/testing/gtest/include/',
     '/netwerk/sctp/src/',
-    '/xpcom/tests/'
+    '/xpcom/libxpcomrt',
 ]
 
-FINAL_LIBRARY = 'xul-gtest'
+USE_LIBS += [
+    '/media/webrtc/trunk/testing/gtest_gtest/gtest',
+    'fallible',
+    'mfbt',
+    'mozglue',
+    'mtransport_standalone',
+    'necko_standalone',
+    'nicer',
+    'nrappkit',
+    'nspr',
+    'nss',
+    'unicharutil_standalone',
+    'xpcomrt',
+]
+
+if not CONFIG['MOZ_NATIVE_NSS'] and not CONFIG['MOZ_FOLD_LIBS']:
+    USE_LIBS += [
+        # Statically linking NSS libssl ensures that we can debug NSS too
+        'static:/security/nss/lib/ssl/ssl',
+    ]
+
+if CONFIG['MOZ_SCTP']:
+    USE_LIBS += [
+        'nksctp_s',
+    ]
+
+USE_LIBS += ['mozglue']
--- a/media/mtransport/test/mtransport_test_utils.h
+++ b/media/mtransport/test/mtransport_test_utils.h
@@ -4,49 +4,115 @@
  * 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/. */
 
 // Original author: ekr@rtfm.com
 
 #ifndef mtransport_test_utils_h__
 #define mtransport_test_utils_h__
 
+#include <iostream>
+
+#include "nspr.h"
 #include "nsCOMPtr.h"
 #include "nsNetCID.h"
+#include "nsXPCOMGlue.h"
+#include "nsXPCOM.h"
 
+#include "nsIComponentManager.h"
+#include "nsIComponentRegistrar.h"
 #include "nsIEventTarget.h"
+#include "nsIIOService.h"
+#include "nsIServiceManager.h"
+#include "nsISocketTransportService.h"
+#include "nsDirectoryServiceUtils.h"
+#include "nsDirectoryServiceDefs.h"
+#ifdef MOZ_CRASHREPORTER
+#include "nsICrashReporter.h"
+#endif
 #include "nsPISocketTransportService.h"
 #include "nsServiceManagerUtils.h"
+#if !defined(MOZILLA_XPCOMRT_API)
+#include "TestHarness.h"
+#else
+#include "XPCOMRTInit.h"
+class ScopedXPCOM {
+public:
+  explicit ScopedXPCOM(const char*)
+  {
+    NS_InitXPCOMRT();
+  }
+  ~ScopedXPCOM()
+  {
+    NS_ShutdownXPCOMRT();
+  }
+};
+#endif
 
 class MtransportTestUtils {
  public:
-  MtransportTestUtils() {
+  MtransportTestUtils() : xpcom_("") {
+    if (!sts_) {
       InitServices();
+    }
   }
 
   ~MtransportTestUtils() {
+    sts_->Shutdown();
   }
 
   void InitServices() {
     nsresult rv;
     sts_target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
     sts_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     MOZ_ASSERT(NS_SUCCEEDED(rv));
+
+#ifdef MOZ_CRASHREPORTER
+    char *crashreporter = PR_GetEnv("MOZ_CRASHREPORTER");
+    if (crashreporter && !strcmp(crashreporter, "1")) {
+      //TODO: move this to an even-more-common location to use in all
+      // C++ unittests
+      crashreporter_ = do_GetService("@mozilla.org/toolkit/crash-reporter;1");
+      if (crashreporter_) {
+        std::cerr << "Setting up crash reporting" << std::endl;
+
+        nsCOMPtr<nsIProperties> dirsvc =
+            do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID);
+        nsCOMPtr<nsIFile> cwd;
+        rv = dirsvc->Get(NS_OS_CURRENT_WORKING_DIR,
+                         NS_GET_IID(nsIFile),
+                         getter_AddRefs(cwd));
+        MOZ_ASSERT(NS_SUCCEEDED(rv));
+        crashreporter_->SetEnabled(true);
+        crashreporter_->SetMinidumpPath(cwd);
+      }
+    }
+#endif
   }
 
   nsCOMPtr<nsIEventTarget> sts_target() { return sts_target_; }
 
  private:
+  ScopedXPCOM xpcom_;
   nsCOMPtr<nsIEventTarget> sts_target_;
   nsCOMPtr<nsPISocketTransportService> sts_;
+#ifdef MOZ_CRASHREPORTER
+  nsCOMPtr<nsICrashReporter> crashreporter_;
+#endif
 };
 
 
+MtransportTestUtils *mtransport_test_utils;
+
+#define SETUP_MTRANSPORT_TEST_UTILS() \
+  MtransportTestUtils utils_; mtransport_test_utils = &utils_
+
 #define CHECK_ENVIRONMENT_FLAG(envname) \
   char *test_flag = getenv(envname); \
   if (!test_flag || strcmp(test_flag, "1")) { \
     printf("To run this test set %s=1 in your environment\n", envname); \
     exit(0); \
   } \
 
 
 #endif
+
--- a/media/mtransport/test/multi_tcp_socket_unittest.cpp
+++ b/media/mtransport/test/multi_tcp_socket_unittest.cpp
@@ -16,61 +16,51 @@
 extern "C" {
 #include "nr_api.h"
 #include "nr_socket.h"
 #include "transport_addr.h"
 #include "ice_ctx.h"
 #include "nr_socket_multi_tcp.h"
 }
 
+#include "mtransport_test_utils.h"
+#include "gtest_ringbuffer_dumper.h"
+
 #include "nr_socket_prsock.h"
 
 #include "stunserver.h"
+// TODO(bcampen@mozilla.com): Big fat hack since the build system doesn't give
+// us a clean way to add object files to a single executable.
+#include "stunserver.cpp"
 
 #include "nricectx.h"
 #include "nricemediastream.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
+MtransportTestUtils *test_utils;
 
 namespace {
 
-class MultiTcpSocketTest : public MtransportTest {
+class MultiTcpSocketTest : public ::testing::Test {
  public:
   MultiTcpSocketTest()
-    :MtransportTest(),
-     socks(3,nullptr),
+    :socks(3,nullptr),
      readable(false),
-     ice_ctx_()
+     ice_ctx_(NrIceCtx::Create("stun", true))
    {}
 
-  void SetUp() {
-    MtransportTest::SetUp();
-
-    ice_ctx_ = NrIceCtx::Create("stun", true);
-
-    test_utils_->sts_target()->Dispatch(
-        WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
-                       NS_DISPATCH_SYNC);
-    test_utils_->sts_target()->Dispatch(
-      WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
-                     NS_DISPATCH_SYNC);
-  }
-
-
-  void TearDown() {
-    test_utils_->sts_target()->Dispatch(
+  ~MultiTcpSocketTest() {
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::Shutdown_s),
             NS_DISPATCH_SYNC);
-
-    MtransportTest::TearDown();
   }
 
   DISALLOW_COPY_ASSIGN(MultiTcpSocketTest);
 
   static void SockReadable(NR_SOCKET s, int how, void *arg) {
     MultiTcpSocketTest *obj=static_cast<MultiTcpSocketTest *>(arg);
     obj->SetReadable(true);
   }
@@ -129,17 +119,17 @@ class MultiTcpSocketTest : public Mtrans
         &MultiTcpSocketTest::SockReadable, this);
     ASSERT_EQ(0, r);
   }
 
   nr_socket *Create(nr_socket_tcp_type tcp_type,
                     std::string stun_server_addr = "",
                     uint16_t stun_server_port = 0) {
     nr_socket *sock=nullptr;
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::Create_s, tcp_type,
                 stun_server_addr, stun_server_port, &sock),
             NS_DISPATCH_SYNC);
     return sock;
   }
 
   void Listen_s(nr_socket *sock) {
@@ -147,29 +137,29 @@ class MultiTcpSocketTest : public Mtrans
     int r=nr_socket_getaddr(sock, &addr);
     ASSERT_EQ(0, r);
     printf("Listening on %s\n", addr.as_string);
     r = nr_socket_listen(sock, 5);
     ASSERT_EQ(0, r);
   }
 
   void Listen(nr_socket *sock) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::Listen_s, sock),
             NS_DISPATCH_SYNC);
   }
 
   void Destroy_s(nr_socket *sock) {
     int r = nr_socket_destroy(&sock);
     ASSERT_EQ(0, r);
   }
 
   void Destroy(nr_socket *sock) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::Destroy_s, sock),
             NS_DISPATCH_SYNC);
   }
 
   void Connect_s(nr_socket *from, nr_socket *to) {
     nr_transport_addr addr_to;
     nr_transport_addr addr_from;
@@ -178,17 +168,17 @@ class MultiTcpSocketTest : public Mtrans
     r=nr_socket_getaddr(from, &addr_from);
     ASSERT_EQ(0, r);
     printf("Connecting from %s to %s\n", addr_from.as_string, addr_to.as_string);
     r=nr_socket_connect(from, &addr_to);
     ASSERT_EQ(0, r);
   }
 
   void Connect(nr_socket *from, nr_socket *to) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::Connect_s, from, to),
             NS_DISPATCH_SYNC);
   }
 
   void ConnectSo_s(nr_socket *so1, nr_socket *so2) {
     nr_transport_addr addr_so1;
     nr_transport_addr addr_so2;
@@ -199,17 +189,17 @@ class MultiTcpSocketTest : public Mtrans
     printf("Connecting SO %s <-> %s\n", addr_so1.as_string, addr_so2.as_string);
     r=nr_socket_connect(so1, &addr_so2);
     ASSERT_EQ(0, r);
     r=nr_socket_connect(so2, &addr_so1);
     ASSERT_EQ(0, r);
   }
 
   void ConnectSo(nr_socket *from, nr_socket *to) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::ConnectSo_s, from, to),
             NS_DISPATCH_SYNC);
   }
 
   void SendDataToAddress_s(nr_socket *from, nr_transport_addr *to, const char *data,
                            size_t len) {
     nr_transport_addr addr_from;
@@ -218,34 +208,34 @@ class MultiTcpSocketTest : public Mtrans
     ASSERT_EQ(0, r);
     printf("Sending %lu bytes %s -> %s\n", (unsigned long)len,
       addr_from.as_string, to->as_string);
     r=nr_socket_sendto(from, data, len, 0, to);
     ASSERT_EQ(0, r);
   }
 
   void SendData(nr_socket *from, nr_transport_addr *to, const char *data, size_t len) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::SendDataToAddress_s, from, to, data,
                 len),
             NS_DISPATCH_SYNC);
   }
 
   void SendDataToSocket_s(nr_socket *from, nr_socket *to, const char *data,
                   size_t len) {
     nr_transport_addr addr_to;
 
     int r=nr_socket_getaddr(to, &addr_to);
     ASSERT_EQ(0, r);
     SendDataToAddress_s(from, &addr_to, data, len);
   }
 
   void SendData(nr_socket *from, nr_socket *to, const char *data, size_t len) {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::SendDataToSocket_s, from, to, data,
                 len),
             NS_DISPATCH_SYNC);
   }
 
   void RecvDataFromAddress_s(nr_transport_addr *expected_from,
                              nr_socket *sent_to,
@@ -276,17 +266,17 @@ class MultiTcpSocketTest : public Mtrans
       r=memcmp(expected_data, received_data, retlen);
       ASSERT_EQ(0, r);
     }
   }
 
   void RecvData(nr_transport_addr *expected_from, nr_socket *sent_to,
                 const char *expected_data = nullptr, size_t expected_len = 0) {
     ASSERT_TRUE_WAIT(IsReadable(), 1000);
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::RecvDataFromAddress_s,
                 expected_from, sent_to, expected_data,
                 expected_len),
             NS_DISPATCH_SYNC);
   }
 
   void RecvDataFromSocket_s(nr_socket *expected_from, nr_socket *sent_to,
@@ -297,17 +287,17 @@ class MultiTcpSocketTest : public Mtrans
     ASSERT_EQ(0, r);
 
     RecvDataFromAddress_s(&addr_from, sent_to, expected_data, expected_len);
   }
 
   void RecvData(nr_socket *expected_from, nr_socket *sent_to,
                 const char *expected_data, size_t expected_len) {
     ASSERT_TRUE_WAIT(IsReadable(), 1000);
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::RecvDataFromSocket_s,
                 expected_from, sent_to, expected_data, expected_len),
             NS_DISPATCH_SYNC);
   }
 
   void RecvDataFailed_s(nr_socket *sent_to, size_t expected_len, int expected_err) {
     SetReadable(false);
@@ -322,17 +312,17 @@ class MultiTcpSocketTest : public Mtrans
                          &retlen, 0, &retaddr);
     ASSERT_EQ(expected_err, r) << "Expecting receive failure " << expected_err
     << " on " << addr_to.as_string;
   }
 
   void RecvDataFailed(nr_socket *sent_to, size_t expected_len,
                       int expected_err) {
     ASSERT_TRUE_WAIT(IsReadable(), 1000);
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
             WrapRunnable(
                 this, &MultiTcpSocketTest::RecvDataFailed_s, sent_to, expected_len,
                 expected_err),
             NS_DISPATCH_SYNC);
   }
 
   void TransferData(nr_socket *from, nr_socket *to, const char *data,
                     size_t len) {
@@ -534,8 +524,38 @@ TEST_F(MultiTcpSocketTest, TestBigData) 
   TransferData(socks[0], socks[1], buf1, sizeof(buf1));
   TransferData(socks[0], socks[1], buf2, sizeof(buf2));
 // opposite dir
   SendData(socks[1], socks[0], buf2, sizeof(buf2));
   SendData(socks[1], socks[0], buf1, sizeof(buf1));
   RecvData(socks[1], socks[0], buf2, sizeof(buf2));
   RecvData(socks[1], socks[0], buf1, sizeof(buf1));
 }
+
+
+int main(int argc, char **argv)
+{
+  test_utils = new MtransportTestUtils();
+  NSS_NoDB_Init(nullptr); // For random number generation
+
+  ::testing::TestEventListeners& listeners =
+        ::testing::UnitTest::GetInstance()->listeners();
+  // Adds a listener to the end.  Google Test takes the ownership.
+  listeners.Append(new test::RingbufferDumper(test_utils));
+
+  test_utils->sts_target()->Dispatch(
+      WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET),
+                     NS_DISPATCH_SYNC);
+  test_utils->sts_target()->Dispatch(
+    WrapRunnableNM(&TestStunTcpServer::GetInstance, AF_INET6),
+                   NS_DISPATCH_SYNC);
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+
+  test_utils->sts_target()->Dispatch(
+    WrapRunnableNM(&TestStunTcpServer::ShutdownInstance), NS_DISPATCH_SYNC);
+
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/nrappkit_unittest.cpp
+++ b/media/mtransport/test/nrappkit_unittest.cpp
@@ -12,45 +12,47 @@
 #include "nsXPCOM.h"
 
 // nrappkit includes
 extern "C" {
 #include "nr_api.h"
 #include "async_timer.h"
 }
 
+#include "mtransport_test_utils.h"
 #include "runnable_utils.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
 
+MtransportTestUtils *test_utils;
+
 namespace {
 
-class TimerTest : public MtransportTest {
+class TimerTest : public ::testing::Test {
  public:
-  TimerTest() : MtransportTest(), handle_(nullptr), fired_(false) {}
-  virtual ~TimerTest() {}
+  TimerTest() : handle_(nullptr), fired_(false) {}
 
   int ArmTimer(int timeout) {
     int ret;
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&ret, this, &TimerTest::ArmTimer_w, timeout),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int ArmCancelTimer(int timeout) {
     int ret;
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&ret, this, &TimerTest::ArmCancelTimer_w, timeout),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int ArmTimer_w(int timeout) {
     return NR_ASYNC_TIMER_SET(timeout, cb, this, &handle_);
@@ -63,31 +65,31 @@ class TimerTest : public MtransportTest 
       return r;
 
     return CancelTimer_w();
   }
 
   int CancelTimer() {
     int ret;
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&ret, this, &TimerTest::CancelTimer_w),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int CancelTimer_w() {
     return NR_async_timer_cancel(handle_);
   }
 
   int Schedule() {
     int ret;
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&ret, this, &TimerTest::Schedule_w),
         NS_DISPATCH_SYNC);
 
     return ret;
   }
 
   int Schedule_w() {
     NR_ASYNC_SCHEDULE(cb, this);
@@ -127,8 +129,19 @@ TEST_F(TimerTest, CancelTimer0) {
   PR_Sleep(100);
   ASSERT_FALSE(fired_);
 }
 
 TEST_F(TimerTest, ScheduleTest) {
   Schedule();
   ASSERT_TRUE_WAIT(fired_, 1000);
 }
+
+int main(int argc, char **argv) {
+  test_utils = new MtransportTestUtils();
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/proxy_tunnel_socket_unittest.cpp
+++ b/media/mtransport/test/proxy_tunnel_socket_unittest.cpp
@@ -18,26 +18,28 @@ extern "C" {
 #include "nr_api.h"
 #include "nr_socket.h"
 #include "nr_proxy_tunnel.h"
 #include "transport_addr.h"
 #include "stun.h"
 }
 
 #include "databuffer.h"
+#include "mtransport_test_utils.h"
 #include "dummysocket.h"
 
 #include "nr_socket_prsock.h"
 #include "nriceresolverfake.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
+MtransportTestUtils *test_utils;
 
 const std::string kRemoteAddr = "192.0.2.133";
 const uint16_t kRemotePort = 3333;
 
 const std::string kProxyHost = "example.com";
 const std::string kProxyAddr = "192.0.2.134";
 const uint16_t kProxyPort = 9999;
 
@@ -101,30 +103,28 @@ class DummyResolver {
     return resolver_;
   }
 
  private:
   nr_resolver_vtbl *vtbl_;
   nr_resolver *resolver_;
 };
 
-class ProxyTunnelSocketTest : public MtransportTest {
+class ProxyTunnelSocketTest : public ::testing::Test {
  public:
   ProxyTunnelSocketTest()
       : socket_impl_(nullptr),
         nr_socket_(nullptr) {}
 
   ~ProxyTunnelSocketTest() {
     nr_socket_destroy(&nr_socket_);
     nr_proxy_tunnel_config_destroy(&config_);
   }
 
-  void SetUp() override {
-    MtransportTest::SetUp();
-
+  void SetUp() {
     nr_resolver_ = resolver_impl_.get_nr_resolver();
 
     int r = nr_str_port_to_transport_addr(
         (char *)kRemoteAddr.c_str(), kRemotePort, IPPROTO_TCP, &remote_addr_);
     ASSERT_EQ(0, r);
 
     r = nr_str_port_to_transport_addr(
         (char *)kProxyAddr.c_str(), kProxyPort, IPPROTO_TCP, &proxy_addr_);
@@ -183,51 +183,47 @@ TEST_F(ProxyTunnelSocketTest, TestCreate
 TEST_F(ProxyTunnelSocketTest, TestConnectProxyAddress) {
   int r = nr_socket_connect(nr_socket_, &remote_addr_);
   ASSERT_EQ(0, r);
 
   ASSERT_EQ(0, nr_transport_addr_cmp(socket_impl_->get_connect_addr(), &proxy_addr_,
         NR_TRANSPORT_ADDR_CMP_MODE_ALL));
 }
 
-// TODO: Reenable once bug 1251212 is fixed
-TEST_F(ProxyTunnelSocketTest, DISABLED_TestConnectProxyRequest) {
+TEST_F(ProxyTunnelSocketTest, TestConnectProxyRequest) {
   Connect();
 
   std::string msg = connect_message(kRemoteAddr, kRemotePort, "", kHelloMessage);
   socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(msg.c_str()), msg.size());
 }
 
-// TODO: Reenable once bug 1251212 is fixed
-TEST_F(ProxyTunnelSocketTest, DISABLED_TestAlpnConnect) {
+TEST_F(ProxyTunnelSocketTest, TestAlpnConnect) {
   const std::string alpn = "this,is,alpn";
   int r = nr_proxy_tunnel_config_set_alpn(config_, alpn.c_str());
   EXPECT_EQ(0, r);
 
   Configure();
   Connect();
 
   std::string msg = connect_message(kRemoteAddr, kRemotePort, alpn, kHelloMessage);
   socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(msg.c_str()), msg.size());
 }
 
-// TODO: Reenable once bug 1251212 is fixed
-TEST_F(ProxyTunnelSocketTest, DISABLED_TestNullAlpnConnect) {
+TEST_F(ProxyTunnelSocketTest, TestNullAlpnConnect) {
   int r = nr_proxy_tunnel_config_set_alpn(config_, nullptr);
   EXPECT_EQ(0, r);
 
   Configure();
   Connect();
 
   std::string msg = connect_message(kRemoteAddr, kRemotePort, "", kHelloMessage);
   socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(msg.c_str()), msg.size());
 }
 
-// TODO: Reenable once bug 1251212 is fixed
-TEST_F(ProxyTunnelSocketTest, DISABLED_TestConnectProxyHostRequest) {
+TEST_F(ProxyTunnelSocketTest, TestConnectProxyHostRequest) {
   nr_proxy_tunnel_config_set_proxy(config_, kProxyHost.c_str(), kProxyPort);
   Configure();
   // Because kProxyHost is a domain name and not an IP address,
   // nr_socket_connect will need to resolve an IP address before continuing.  It
   // does that, and assumes that resolving the IP will take some time, so it
   // returns R_WOULDBLOCK.
   //
   // However, In this test setup, the resolution happens inline immediately, so
@@ -240,18 +236,17 @@ TEST_F(ProxyTunnelSocketTest, DISABLED_T
   // report an error when it doesn't need any further assistance from the
   // calling code, but that's pretty minor.
   Connect(R_WOULDBLOCK);
 
   std::string msg = connect_message(kRemoteAddr, kRemotePort, "", kHelloMessage);
   socket_impl_->CheckWriteBuffer(reinterpret_cast<const uint8_t *>(msg.c_str()), msg.size());
 }
 
-// TODO: Reenable once bug 1251212 is fixed
-TEST_F(ProxyTunnelSocketTest, DISABLED_TestConnectProxyWrite) {
+TEST_F(ProxyTunnelSocketTest, TestConnectProxyWrite) {
   Connect();
 
   socket_impl_->ClearWriteBuffer();
 
   size_t written = 0;
   int r = nr_socket_write(nr_socket_, kHelloMessage.c_str(), kHelloMessage.size(), &written, 0);
   EXPECT_EQ(0, r);
   EXPECT_EQ(kHelloMessage.size(), written);
@@ -339,8 +334,23 @@ TEST_F(ProxyTunnelSocketTest, TestConnec
   socket_impl_->SetReadBuffer(reinterpret_cast<const uint8_t *>(kGarbageMessage.c_str()),
       kGarbageMessage.size());
 
   char buf[4096];
   size_t read = 0;
   r = nr_socket_read(nr_socket_, buf, sizeof(buf), &read, 0);
   ASSERT_EQ(0ul, read);
 }
+
+int main(int argc, char **argv)
+{
+  test_utils = new MtransportTestUtils();
+  NSS_NoDB_Init(nullptr);
+  NSS_SetDomesticPolicy();
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/rlogringbuffer_unittest.cpp
+++ b/media/mtransport/test/rlogringbuffer_unittest.cpp
@@ -30,24 +30,16 @@ class RLogRingBufferTest : public ::test
     RLogRingBufferTest() {
       Init();
     }
 
     ~RLogRingBufferTest() {
       Free();
     }
 
-    static void SetUpTestCase() {
-      NR_reg_init(NR_REG_MODE_LOCAL);
-      r_log_init();
-      /* Would be nice to be able to unregister in the fixture */
-      const char* facility = "rlogringbuffer_test";
-      r_log_register(const_cast<char*>(facility), &NR_LOG_TEST);
-    }
-
     void Init() {
       RLogRingBuffer::CreateInstance();
     }
 
     void Free() {
       RLogRingBuffer::DestroyInstance();
     }
 
@@ -257,8 +249,21 @@ TEST_F(RLogRingBufferTest, TestReInit) {
   r_log(NR_LOG_TEST, LOG_INFO, "Test4");
   r_log(NR_LOG_TEST, LOG_INFO, "Test5");
   r_log(NR_LOG_TEST, LOG_INFO, "Test6");
   ReInit();
   std::deque<std::string> logs;
   RLogRingBuffer::GetInstance()->GetAny(0, &logs);
   ASSERT_EQ(0U, logs.size());
 }
+
+int main(int argc, char** argv) {
+  NR_reg_init(NR_REG_MODE_LOCAL);
+  r_log_init();
+  /* Would be nice to be able to register/unregister in the fixture */
+  const char* facility = "rlogringbuffer_test";
+  r_log_register(const_cast<char*>(facility), &NR_LOG_TEST);
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  return rv;
+}
+
--- a/media/mtransport/test/runnable_utils_unittest.cpp
+++ b/media/mtransport/test/runnable_utils_unittest.cpp
@@ -21,22 +21,24 @@
 #include "nsIServiceManager.h"
 #include "nsISocketTransportService.h"
 
 #include "nsASocketHandler.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
 #include "runnable_utils.h"
+#include "mtransport_test_utils.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
+MtransportTestUtils *test_utils;
 
 namespace {
 
 class Destructor {
  private:
   ~Destructor() {
     std::cerr << "Destructor called" << std::endl;
     *destroyed_ = true;
@@ -77,19 +79,19 @@ class TargetClass {
 
   void destructor_target_ref(RefPtr<Destructor> destructor) {
   }
 
   int *ran_;
 };
 
 
-class RunnableArgsTest : public MtransportTest {
+class RunnableArgsTest : public ::testing::Test {
  public:
-  RunnableArgsTest() : MtransportTest(), ran_(0), cl_(&ran_){}
+  RunnableArgsTest() : ran_(0), cl_(&ran_){}
 
   void Test1Arg() {
     nsRunnable * r = WrapRunnable(&cl_, &TargetClass::m1, 1);
     r->Run();
     ASSERT_EQ(1, ran_);
   }
 
   void Test2Args() {
@@ -98,23 +100,21 @@ class RunnableArgsTest : public Mtranspo
     ASSERT_EQ(2, ran_);
   }
 
  private:
   int ran_;
   TargetClass cl_;
 };
 
-class DispatchTest : public MtransportTest {
+class DispatchTest : public ::testing::Test {
  public:
-  DispatchTest() : MtransportTest(), ran_(0), cl_(&ran_) {}
+  DispatchTest() : ran_(0), cl_(&ran_) {}
 
   void SetUp() {
-    MtransportTest::SetUp();
-
     nsresult rv;
     target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
   }
 
   void Test1Arg() {
     nsRunnable* r = WrapRunnable(&cl_, &TargetClass::m1, 1);
     target_->Dispatch(r, NS_DISPATCH_SYNC);
@@ -180,26 +180,26 @@ void SetNonMethod(TargetClass *cl, int x
 
 int SetNonMethodRet(TargetClass *cl, int x) {
   cl->m1(x);
 
   return x;
 }
 
 TEST_F(DispatchTest, TestNonMethod) {
-  test_utils_->sts_target()->Dispatch(
+  test_utils->sts_target()->Dispatch(
       WrapRunnableNM(SetNonMethod, &cl_, 10), NS_DISPATCH_SYNC);
 
   ASSERT_EQ(1, ran_);
 }
 
 TEST_F(DispatchTest, TestNonMethodRet) {
   int z;
 
-  test_utils_->sts_target()->Dispatch(
+  test_utils->sts_target()->Dispatch(
       WrapRunnableNMRet(&z, SetNonMethodRet, &cl_, 10), NS_DISPATCH_SYNC);
 
   ASSERT_EQ(1, ran_);
   ASSERT_EQ(10, z);
 }
 
 TEST_F(DispatchTest, TestDestructor) {
   bool destroyed = false;
@@ -220,8 +220,21 @@ TEST_F(DispatchTest, TestDestructorRef) 
                     NS_DISPATCH_SYNC);
   ASSERT_FALSE(destroyed);
   destructor = nullptr;
   ASSERT_TRUE(destroyed);
 }
 
 
 } // end of namespace
+
+
+int main(int argc, char **argv) {
+  test_utils = new MtransportTestUtils();
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  delete test_utils;
+  return rv;
+}
+
--- a/media/mtransport/test/sctp_unittest.cpp
+++ b/media/mtransport/test/sctp_unittest.cpp
@@ -18,26 +18,28 @@
 #include "nsComponentManagerUtils.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 
 #include "transportflow.h"
 #include "transportlayer.h"
 #include "transportlayerloopback.h"
 
+#include "mtransport_test_utils.h"
 #include "runnable_utils.h"
 #include "usrsctp.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 
 using namespace mozilla;
 
+MtransportTestUtils *test_utils;
 static bool sctp_logging = false;
 static int port_number = 5000;
 
 namespace {
 
 class TransportTestPeer;
 
 class SendPeriodic : public nsITimerCallback {
@@ -56,26 +58,24 @@ class SendPeriodic : public nsITimerCall
   int to_send_;
 };
 
 NS_IMPL_ISUPPORTS(SendPeriodic, nsITimerCallback)
 
 
 class TransportTestPeer : public sigslot::has_slots<> {
  public:
-  TransportTestPeer(std::string name, int local_port, int remote_port,
-                    MtransportTestUtils* utils)
+  TransportTestPeer(std::string name, int local_port, int remote_port)
       : name_(name), connected_(false),
         sent_(0), received_(0),
         flow_(new TransportFlow()),
         loopback_(new TransportLayerLoopback()),
         sctp_(usrsctp_socket(AF_CONN, SOCK_STREAM, IPPROTO_SCTP, receive_cb, nullptr, 0, nullptr)),
         timer_(do_CreateInstance(NS_TIMER_CONTRACTID)),
-        periodic_(nullptr),
-        test_utils_(utils) {
+        periodic_(nullptr) {
     std::cerr << "Creating TransportTestPeer; flow=" <<
         static_cast<void *>(flow_.get()) <<
         " local=" << local_port <<
         " remote=" << remote_port << std::endl;
 
     usrsctp_register_address(static_cast<void *>(this));
     int r = usrsctp_set_non_blocking(sctp_, 1);
     EXPECT_GE(r, 0);
@@ -119,25 +119,25 @@ class TransportTestPeer : public sigslot
   }
 
   ~TransportTestPeer() {
     std::cerr << "Destroying sctp connection flow=" <<
         static_cast<void *>(flow_.get()) << std::endl;
     usrsctp_close(sctp_);
     usrsctp_deregister_address(static_cast<void *>(this));
 
-    test_utils_->sts_target()->Dispatch(WrapRunnable(this,
+    test_utils->sts_target()->Dispatch(WrapRunnable(this,
                                                    &TransportTestPeer::Disconnect_s),
                                       NS_DISPATCH_SYNC);
 
     std::cerr << "~TransportTestPeer() completed" << std::endl;
   }
 
   void ConnectSocket(TransportTestPeer *peer) {
-    test_utils_->sts_target()->Dispatch(WrapRunnable(
+    test_utils->sts_target()->Dispatch(WrapRunnable(
         this, &TransportTestPeer::ConnectSocket_s, peer),
                                        NS_DISPATCH_SYNC);
   }
 
   void ConnectSocket_s(TransportTestPeer *peer) {
     loopback_->Connect(peer->loopback_);
 
     ASSERT_EQ((nsresult)NS_OK, flow_->PushLayer(loopback_));
@@ -165,17 +165,17 @@ class TransportTestPeer : public sigslot
 
   void Disconnect() {
     loopback_->Disconnect();
   }
 
 
   void StartTransfer(size_t to_send) {
     periodic_ = new SendPeriodic(this, to_send);
-    timer_->SetTarget(test_utils_->sts_target());
+    timer_->SetTarget(test_utils->sts_target());
     timer_->InitWithCallback(periodic_, 10, nsITimer::TYPE_REPEATING_SLACK);
   }
 
   void SendOne() {
     unsigned char buf[100];
     memset(buf, sent_ & 0xff, sizeof(buf));
 
     struct sctp_sndinfo info;
@@ -210,17 +210,17 @@ class TransportTestPeer : public sigslot
     memcpy(buffer, data, len);
 
     // Uses DISPATCH_NORMAL to avoid possible deadlocks when we're called
     // from MainThread especially during shutdown (same as DataChannels).
     // RUN_ON_THREAD short-circuits if already on the STS thread, which is
     // normal for most transfers outside of connect() and close().  Passes
     // a refptr to flow_ to avoid any async deletion issues (since we can't
     // make 'this' into a refptr as it isn't refcounted)
-    RUN_ON_THREAD(test_utils_->sts_target(), WrapRunnableNM(
+    RUN_ON_THREAD(test_utils->sts_target(), WrapRunnableNM(
         &TransportTestPeer::SendPacket_s, buffer, len, flow_),
                   NS_DISPATCH_NORMAL);
 
     return 0;
   }
 
   void PacketReceived(TransportFlow * flow, const unsigned char* data,
                       size_t len) {
@@ -291,36 +291,41 @@ class TransportTestPeer : public sigslot
   RefPtr<TransportFlow> flow_;
   TransportLayerLoopback *loopback_;
 
   struct sockaddr_conn local_addr_;
   struct sockaddr_conn remote_addr_;
   struct socket *sctp_;
   nsCOMPtr<nsITimer> timer_;
   RefPtr<SendPeriodic> periodic_;
-  MtransportTestUtils* test_utils_;
 };
 
 
 // Implemented here because it calls a method of TransportTestPeer
 NS_IMETHODIMP SendPeriodic::Notify(nsITimer *timer) {
   peer_->SendOne();
   --to_send_;
   if (!to_send_) {
     timer->Cancel();
   }
   return NS_OK;
 }
 
-class SctpTransportTest : public MtransportTest {
+class TransportTest : public ::testing::Test {
  public:
-  SctpTransportTest() {
+  TransportTest() {
   }
 
-  ~SctpTransportTest() {
+  ~TransportTest() {
+    if (p1_)
+      p1_->Disconnect();
+    if (p2_)
+      p2_->Disconnect();
+    delete p1_;
+    delete p2_;
   }
 
   static void debug_printf(const char *format, ...) {
     va_list ap;
 
     va_start(ap, format);
     vprintf(format, ap);
     va_end(ap);
@@ -331,36 +336,27 @@ class SctpTransportTest : public Mtransp
     if (sctp_logging) {
       usrsctp_init(0, &TransportTestPeer::conn_output, debug_printf);
       usrsctp_sysctl_set_sctp_debug_on(0xffffffff);
     } else {
       usrsctp_init(0, &TransportTestPeer::conn_output, nullptr);
     }
   }
 
-  void TearDown() override {
-    if (p1_)
-      p1_->Disconnect();
-    if (p2_)
-      p2_->Disconnect();
-    delete p1_;
-    delete p2_;
-
-    MtransportTest::TearDown();
+  void SetUp() {
   }
 
-
   void ConnectSocket(int p1port = 0, int p2port = 0) {
     if (!p1port)
       p1port = port_number++;
     if (!p2port)
       p2port = port_number++;
 
-    p1_ = new TransportTestPeer("P1", p1port, p2port, test_utils_);
-    p2_ = new TransportTestPeer("P2", p2port, p1port, test_utils_);
+    p1_ = new TransportTestPeer("P1", p1port, p2port);
+    p2_ = new TransportTestPeer("P2", p2port, p1port);
 
     p1_->ConnectSocket(p2_);
     p2_->ConnectSocket(p1_);
     ASSERT_TRUE_WAIT(p1_->connected(), 2000);
     ASSERT_TRUE_WAIT(p2_->connected(), 2000);
   }
 
   void TestTransfer(int expected = 1) {
@@ -371,23 +367,40 @@ class SctpTransportTest : public Mtransp
     std::cerr << "P2 received " << p2_->received() << std::endl;
   }
 
  protected:
   TransportTestPeer *p1_;
   TransportTestPeer *p2_;
 };
 
-TEST_F(SctpTransportTest, TestConnect) {
+TEST_F(TransportTest, TestConnect) {
   ConnectSocket();
 }
 
-TEST_F(SctpTransportTest, TestConnectSymmetricalPorts) {
+TEST_F(TransportTest, TestConnectSymmetricalPorts) {
   ConnectSocket(5002,5002);
 }
 
-TEST_F(SctpTransportTest, TestTransfer) {
+TEST_F(TransportTest, TestTransfer) {
   ConnectSocket();
   TestTransfer(50);
 }
 
 
 }  // end namespace
+
+int main(int argc, char **argv)
+{
+  test_utils = new MtransportTestUtils();
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  for(int i=0; i<argc; i++) {
+    if (!strcmp(argv[i],"-v")) {
+      sctp_logging = true;
+    }
+  }
+
+  int rv = RUN_ALL_TESTS();
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/simpletokenbucket_unittest.cpp
+++ b/media/mtransport/test/simpletokenbucket_unittest.cpp
@@ -100,8 +100,16 @@ TEST(SimpleTokenBucketTest, TestEmptyThe
 
 TEST(SimpleTokenBucketTest, TestNoOverflow) {
   TestSimpleTokenBucket b(10, 1);
   ASSERT_EQ(10U, b.getTokens(10));
   ASSERT_EQ(0U, b.getTokens(1));
   b.fastForward(50000);
   ASSERT_EQ(10U, b.getTokens(11));
 }
+
+int main(int argc, char** argv) {
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  return rv;
+}
+
--- a/media/mtransport/test/sockettransportservice_unittest.cpp
+++ b/media/mtransport/test/sockettransportservice_unittest.cpp
@@ -19,26 +19,28 @@
 #include "nsIIOService.h"
 #include "nsIServiceManager.h"
 #include "nsISocketTransportService.h"
 
 #include "nsASocketHandler.h"
 #include "nsServiceManagerUtils.h"
 #include "nsThreadUtils.h"
 
+#include "mtransport_test_utils.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
+MtransportTestUtils *test_utils;
+
 namespace {
-class SocketTransportServiceTest : public MtransportTest {
+class SocketTransportServiceTest : public ::testing::Test {
  public:
-  SocketTransportServiceTest() : MtransportTest(),
-                                 received_(0),
+  SocketTransportServiceTest() : received_(0),
                                  readpipe_(nullptr),
                                  writepipe_(nullptr),
                                  registered_(false) {
   }
 
   ~SocketTransportServiceTest() {
     if (readpipe_)
       PR_Close(readpipe_);
@@ -136,18 +138,16 @@ class SocketHandler : public nsASocketHa
 
  private:
   SocketTransportServiceTest *test_;
 };
 
 NS_IMPL_ISUPPORTS0(SocketHandler)
 
 void SocketTransportServiceTest::SetUp() {
-  MtransportTest::SetUp();
-
   // Get the transport service as a dispatch target
   nsresult rv;
   target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
 
   // Get the transport service as a transport service
   stservice_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
   ASSERT_TRUE(NS_SUCCEEDED(rv));
@@ -199,8 +199,20 @@ TEST_F(SocketTransportServiceTest, SendE
 }
 
 TEST_F(SocketTransportServiceTest, SendPacket) {
   SendPacket();
 }
 
 
 }  // end namespace
+
+
+int main(int argc, char **argv) {
+  test_utils = new MtransportTestUtils();
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/test_nr_socket_unittest.cpp
+++ b/media/mtransport/test/test_nr_socket_unittest.cpp
@@ -20,52 +20,45 @@ extern "C" {
 
 #include "test_nr_socket.h"
 
 #include "nsCOMPtr.h"
 #include "nsNetCID.h"
 #include "nsServiceManagerUtils.h"
 #include "nsAutoPtr.h"
 #include "runnable_utils.h"
+#include "mtransport_test_utils.h"
 
 #include <vector>
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 #define DATA_BUF_SIZE 1024
 
 namespace mozilla {
 
-class TestNrSocketTest : public MtransportTest {
+class TestNrSocketTest : public ::testing::Test {
  public:
   TestNrSocketTest() :
-    MtransportTest(),
     wait_done_for_main_(false),
     sts_(),
     public_addrs_(),
     private_addrs_(),
     nats_() {
-  }
-
-  void SetUp() override {
-    MtransportTest::SetUp();
-
     // Get the transport service as a dispatch target
     nsresult rv;
     sts_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     EXPECT_TRUE(NS_SUCCEEDED(rv)) << "Failed to get STS: " << (int)rv;
   }
 
-  void TearDown() override {
+  ~TestNrSocketTest() {
     sts_->Dispatch(WrapRunnable(this, &TestNrSocketTest::TearDown_s),
                    NS_DISPATCH_SYNC);
-
-    MtransportTest::TearDown();
   }
 
   void TearDown_s() {
     public_addrs_.clear();
     private_addrs_.clear();
     nats_.clear();
     sts_ = nullptr;
   }
@@ -856,8 +849,23 @@ TEST_F(TestNrSocketTest, NoConnectivityP
 {
   RefPtr<TestNat> nat(CreatePrivateAddrs(1, "127.0.0.1", IPPROTO_TCP));
   nat->filtering_type_ = TestNat::ENDPOINT_INDEPENDENT;
   nat->mapping_type_ = TestNat::ENDPOINT_INDEPENDENT;
   CreatePublicAddrs(1, "127.0.0.1", IPPROTO_TCP);
 
   ASSERT_FALSE(CheckTcpConnectivity(public_addrs_[0], private_addrs_[0]));
 }
+
+int main(int argc, char **argv)
+{
+  // Inits STS and some other stuff.
+  MtransportTestUtils test_utils;
+
+  NR_reg_init(NR_REG_MODE_LOCAL);
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+
+  return rv;
+}
--- a/media/mtransport/test/transport_unittests.cpp
+++ b/media/mtransport/test/transport_unittests.cpp
@@ -30,25 +30,28 @@
 #include "nricemediastream.h"
 #include "transportflow.h"
 #include "transportlayer.h"
 #include "transportlayerdtls.h"
 #include "transportlayerice.h"
 #include "transportlayerlog.h"
 #include "transportlayerloopback.h"
 
+#include "mtransport_test_utils.h"
 #include "runnable_utils.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 using namespace mozilla;
 MOZ_MTLOG_MODULE("mtransport")
 
+MtransportTestUtils *test_utils;
+
 
 const uint8_t kTlsChangeCipherSpecType = 0x14;
 const uint8_t kTlsHandshakeType =        0x16;
 
 const uint8_t kTlsHandshakeCertificate = 0x0b;
 const uint8_t kTlsHandshakeServerKeyExchange = 0x0c;
 
 const uint8_t kTlsFakeChangeCipherSpec[] = {
@@ -428,35 +431,34 @@ class TlsServerKeyExchangeECDHE {
   }
 
   DataBuffer public_key_;
 };
 
 namespace {
 class TransportTestPeer : public sigslot::has_slots<> {
  public:
-  TransportTestPeer(nsCOMPtr<nsIEventTarget> target, std::string name, MtransportTestUtils* utils)
+  TransportTestPeer(nsCOMPtr<nsIEventTarget> target, std::string name)
       : name_(name), target_(target),
         received_packets_(0),received_bytes_(0),flow_(new TransportFlow(name)),
         loopback_(new TransportLayerLoopback()),
         logging_(new TransportLayerLogging()),
         lossy_(new TransportLayerLossy()),
         dtls_(new TransportLayerDtls()),
         identity_(DtlsIdentity::Generate()),
         ice_ctx_(NrIceCtx::Create(name,
                                   name == "P2" ?
                                   TransportLayerDtls::CLIENT :
                                   TransportLayerDtls::SERVER)),
         streams_(), candidates_(),
         peer_(nullptr),
         gathering_complete_(false),
         enabled_cipersuites_(),
         disabled_cipersuites_(),
-        reuse_dhe_key_(false),
-        test_utils_(utils) {
+        reuse_dhe_key_(false) {
     std::vector<NrIceStunServer> stun_servers;
     UniquePtr<NrIceStunServer> server(NrIceStunServer::Create(
         std::string((char *)"stun.services.mozilla.com"), 3478));
     stun_servers.push_back(*server);
     EXPECT_TRUE(NS_SUCCEEDED(ice_ctx_->SetStunServers(stun_servers)));
 
     dtls_->SetIdentity(identity_);
     dtls_->SetRole(name == "P2" ?
@@ -467,17 +469,17 @@ class TransportTestPeer : public sigslot
                                              fingerprint_,
                                              sizeof(fingerprint_),
                                              &fingerprint_len_);
     EXPECT_TRUE(NS_SUCCEEDED(res));
     EXPECT_EQ(20u, fingerprint_len_);
   }
 
   ~TransportTestPeer() {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnable(this, &TransportTestPeer::DestroyFlow),
       NS_DISPATCH_SYNC);
   }
 
 
   void DestroyFlow() {
     if (flow_) {
       loopback_->Disconnect();
@@ -584,17 +586,17 @@ class TransportTestPeer : public sigslot
     }
     for (auto it = disabled_cipersuites_.begin();
          it != disabled_cipersuites_.end(); ++it) {
       SSL_CipherPrefSet(fd, *it, PR_FALSE);
     }
   }
 
   void ConnectSocket(TransportTestPeer *peer) {
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, & TransportTestPeer::ConnectSocket_s,
                                peer),
                   NS_DISPATCH_SYNC);
   }
 
   void InitIce() {
     nsresult res;
 
@@ -623,28 +625,28 @@ class TransportTestPeer : public sigslot
     ice_->SetParameters(ice_ctx_, stream, 1);
 
     // Assemble the stack
     nsAutoPtr<std::queue<mozilla::TransportLayer *> > layers(
       new std::queue<mozilla::TransportLayer *>);
     layers->push(ice_);
     layers->push(dtls_);
 
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnableRet(&res, flow_, &TransportFlow::PushLayers, layers),
       NS_DISPATCH_SYNC);
 
     ASSERT_EQ((nsresult)NS_OK, res);
 
     // Listen for media events
     flow_->SignalPacketReceived.connect(this, &TransportTestPeer::PacketReceived);
     flow_->SignalStateChange.connect(this, &TransportTestPeer::StateChanged);
 
     // Start gathering
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&res, ice_ctx_, &NrIceCtx::StartGathering),
         NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   void ConnectIce(TransportTestPeer *peer) {
     peer_ = peer;
 
@@ -674,41 +676,41 @@ class TransportTestPeer : public sigslot
 
     // Don't send to the other side
     if (!peer_) {
       gathering_complete_ = true;
       return;
     }
 
     // First send attributes
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnableRet(&res, peer_->ice_ctx_,
                       &NrIceCtx::ParseGlobalAttributes,
                       ice_ctx_->GetGlobalAttributes()),
       NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
 
     for (size_t i=0; i<streams_.size(); ++i) {
-      test_utils_->sts_target()->Dispatch(
+      test_utils->sts_target()->Dispatch(
         WrapRunnableRet(&res, peer_->streams_[i], &NrIceMediaStream::ParseAttributes,
                         candidates_[streams_[i]->name()]), NS_DISPATCH_SYNC);
 
       ASSERT_TRUE(NS_SUCCEEDED(res));
     }
 
     // Start checks on the other peer.
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnableRet(&res, peer_->ice_ctx_, &NrIceCtx::StartChecks),
       NS_DISPATCH_SYNC);
     ASSERT_TRUE(NS_SUCCEEDED(res));
   }
 
   TransportResult SendPacket(const unsigned char* data, size_t len) {
     TransportResult ret;
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnableRet(&ret, flow_, &TransportFlow::SendPacket, data, len),
       NS_DISPATCH_SYNC);
 
     return ret;
   }
 
 
   void StateChanged(TransportFlow *flow, TransportLayer::State state) {
@@ -750,17 +752,17 @@ class TransportTestPeer : public sigslot
 
   void SetReuseECDHEKey() {
     reuse_dhe_key_ = true;
   }
 
   TransportLayer::State state() {
     TransportLayer::State tstate;
 
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnableRet(&tstate, flow_, &TransportFlow::state));
 
     return tstate;
   }
 
   bool connected() {
     return state() == TransportLayer::TS_OPEN;
   }
@@ -771,30 +773,30 @@ class TransportTestPeer : public sigslot
 
   size_t receivedPackets() { return received_packets_; }
 
   size_t receivedBytes() { return received_bytes_; }
 
   uint16_t cipherSuite() const {
     nsresult rv;
     uint16_t cipher;
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnableRet(&rv, dtls_, &TransportLayerDtls::GetCipherSuite,
                                   &cipher));
 
     if (NS_FAILED(rv)) {
       return TLS_NULL_WITH_NULL_NULL; // i.e., not good
     }
     return cipher;
   }
 
   uint16_t srtpCipher() const {
     nsresult rv;
     uint16_t cipher;
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnableRet(&rv, dtls_, &TransportLayerDtls::GetSrtpCipher,
                                   &cipher));
     if (NS_FAILED(rv)) {
       return 0; // the SRTP equivalent of TLS_NULL_WITH_NULL_NULL
     }
     return cipher;
   }
 
@@ -815,55 +817,51 @@ class TransportTestPeer : public sigslot
   std::map<std::string, std::vector<std::string> > candidates_;
   TransportTestPeer *peer_;
   bool gathering_complete_;
   unsigned char fingerprint_[TransportLayerDtls::kMaxDigestLength];
   size_t fingerprint_len_;
   std::vector<uint16_t> enabled_cipersuites_;
   std::vector<uint16_t> disabled_cipersuites_;
   bool reuse_dhe_key_;
-  MtransportTestUtils* test_utils_;
 };
 
 
-class TransportTest : public MtransportTest {
+class TransportTest : public ::testing::Test {
  public:
   TransportTest() {
     fds_[0] = nullptr;
     fds_[1] = nullptr;
   }
 
-  void TearDown() override {
+  ~TransportTest() {
     delete p1_;
     delete p2_;
 
     //    Can't detach these
     //    PR_Close(fds_[0]);
     //    PR_Close(fds_[1]);
-    MtransportTest::TearDown();
   }
 
   void DestroyPeerFlows() {
     p1_->DisconnectDestroyFlow();
     p2_->DisconnectDestroyFlow();
   }
 
-  void SetUp() override {
-    MtransportTest::SetUp();
-
+  void SetUp() {
     nsresult rv;
     target_ = do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
     ASSERT_TRUE(NS_SUCCEEDED(rv));
 
     Reset();
   }
 
   void Reset() {
-    p1_ = new TransportTestPeer(target_, "P1", test_utils_);
-    p2_ = new TransportTestPeer(target_, "P2", test_utils_);
+    p1_ = new TransportTestPeer(target_, "P1");
+    p2_ = new TransportTestPeer(target_, "P2");
   }
 
   void SetupSrtp() {
     p1_->SetupSrtp();
     p2_->SetupSrtp();
   }
 
   void SetDtlsPeer(int digests = 1, unsigned int damage = 0) {
@@ -938,20 +936,20 @@ class TransportTest : public MtransportT
 
     std::cerr << "Received == " << p2_->receivedPackets() << " packets" << std::endl;
     ASSERT_TRUE_WAIT(count == p2_->receivedPackets(), 10000);
     ASSERT_TRUE((count * sizeof(buf)) == p2_->receivedBytes());
   }
 
  protected:
   void ConnectSocketInternal() {
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnable(p1_, &TransportTestPeer::ConnectSocket, p2_),
       NS_DISPATCH_SYNC);
-    test_utils_->sts_target()->Dispatch(
+    test_utils->sts_target()->Dispatch(
       WrapRunnable(p2_, &TransportTestPeer::ConnectSocket, p1_),
       NS_DISPATCH_SYNC);
   }
 
   PRFileDesc *fds_[2];
   TransportTestPeer *p1_;
   TransportTestPeer *p2_;
   nsCOMPtr<nsIEventTarget> target_;
@@ -1321,8 +1319,22 @@ TEST(PushTests, LayersFail) {
   rv = flow->PushLayers(layers);
 
   ASSERT_TRUE(NS_FAILED(rv));
   ASSERT_EQ(true, destroyed2);
   ASSERT_EQ(true, destroyed3);
 }
 
 }  // end namespace
+
+int main(int argc, char **argv)
+{
+  test_utils = new MtransportTestUtils();
+
+  NSS_NoDB_Init(nullptr);
+  NSS_SetDomesticPolicy();
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  delete test_utils;
+  return rv;
+}
--- a/media/mtransport/test/turn_unittest.cpp
+++ b/media/mtransport/test/turn_unittest.cpp
@@ -48,16 +48,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 #include "nspr.h"
 #include "nss.h"
 #include "ssl.h"
 
 #include "mozilla/Scoped.h"
 #include "nsThreadUtils.h"
 #include "nsXPCOM.h"
 
+#include "mtransport_test_utils.h"
 #include "runnable_utils.h"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
 #define USE_TURN
 
@@ -76,41 +77,43 @@ extern "C" {
 #include "stun_client_ctx.h"
 #include "turn_client_ctx.h"
 }
 
 #include "nricemediastream.h"
 #include "nricectx.h"
 
 
+MtransportTestUtils *test_utils;
+
 using namespace mozilla;
 
-static std::string kDummyTurnServer("192.0.2.1");  // From RFC 5737
+std::string g_turn_server;
+std::string g_turn_user;
+std::string g_turn_password;
 
-class TurnClient : public MtransportTest {
+std::string kDummyTurnServer("192.0.2.1");  // From RFC 5737
+
+class TurnClient : public ::testing::Test {
  public:
   TurnClient()
-      : MtransportTest(),
+      : turn_server_(g_turn_server),
         real_socket_(nullptr),
         net_socket_(nullptr),
         buffered_socket_(nullptr),
         net_fd_(nullptr),
         turn_ctx_(nullptr),
         allocated_(false),
         received_(0),
         protocol_(IPPROTO_UDP) {
   }
 
   ~TurnClient() {
   }
 
-  static void SetUpTestCase() {
-    NrIceCtx::Init(false, false, false);
-  }
-
   void SetTcp() {
     protocol_ = IPPROTO_TCP;
   }
 
   void Init_s() {
     int r;
     nr_transport_addr addr;
     r = nr_ip4_port_to_transport_addr(0, 0, protocol_, &addr);
@@ -129,21 +132,21 @@ class TurnClient : public MtransportTest
       net_socket_ = real_socket_;
     }
 
     r = nr_str_port_to_transport_addr(turn_server_.c_str(), 3478,
       protocol_, &addr);
     ASSERT_EQ(0, r);
 
     std::vector<unsigned char> password_vec(
-        turn_password_.begin(), turn_password_.end());
+        g_turn_password.begin(), g_turn_password.end());
     Data password;
     INIT_DATA(password, &password_vec[0], password_vec.size());
     r = nr_turn_client_ctx_create("test", net_socket_,
-                                  turn_user_.c_str(),
+                                  g_turn_user.c_str(),
                                   &password,
                                   &addr, &turn_ctx_);
     ASSERT_EQ(0, r);
 
     r = nr_socket_getfd(net_socket_, &net_fd_);
     ASSERT_EQ(0, r);
 
     NR_ASYNC_WAIT(net_fd_, NR_ASYNC_WAIT_READ, socket_readable_cb,
@@ -155,33 +158,33 @@ class TurnClient : public MtransportTest
     if (net_fd_) {
       NR_ASYNC_CANCEL(net_fd_, NR_ASYNC_WAIT_READ);
     }
 
     nr_socket_destroy(&buffered_socket_);
   }
 
   void TearDown() {
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, &TurnClient::TearDown_s),
                   NS_DISPATCH_SYNC);
   }
 
   void Allocate_s() {
     Init_s();
     ASSERT_TRUE(turn_ctx_);
 
     int r = nr_turn_client_allocate(turn_ctx_,
                                     allocate_success_cb,
                                     this);
     ASSERT_EQ(0, r);
   }
 
   void Allocate(bool expect_success=true) {
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, &TurnClient::Allocate_s),
                   NS_DISPATCH_SYNC);
 
     if (expect_success) {
       ASSERT_TRUE_WAIT(allocated_, 5000);
     }
     else {
       PR_Sleep(10000);
@@ -211,17 +214,17 @@ class TurnClient : public MtransportTest
     ASSERT_TRUE(turn_ctx_);
 
     std::cerr << "De-Allocating..." << std::endl;
     int r = nr_turn_client_deallocate(turn_ctx_);
     ASSERT_EQ(0, r);
   }
 
   void Deallocate() {
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, &TurnClient::Deallocate_s),
                   NS_DISPATCH_SYNC);
   }
 
   void RequestPermission_s(const std::string& target) {
     nr_transport_addr addr;
     int r;
 
@@ -240,17 +243,17 @@ class TurnClient : public MtransportTest
                                       &addr);
     ASSERT_EQ(0, r);
 
     r = nr_turn_client_ensure_perm(turn_ctx_, &addr);
     ASSERT_EQ(0, r);
   }
 
   void RequestPermission(const std::string& target) {
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, &TurnClient::RequestPermission_s, target),
                   NS_DISPATCH_SYNC);
 
   }
 
   void Readable(NR_SOCKET s, int how, void *arg) {
     // Re-arm
     std::cerr << "Socket is readable" << std::endl;
@@ -338,17 +341,17 @@ class TurnClient : public MtransportTest
                                             test, sizeof(test), 0,
                                             &addr);
     if (expect_return >= 0) {
       ASSERT_EQ(expect_return, r);
     }
   }
 
   void SendTo(const std::string& target, int expect_return=0) {
-    RUN_ON_THREAD(test_utils_->sts_target(),
+    RUN_ON_THREAD(test_utils->sts_target(),
                   WrapRunnable(this, &TurnClient::SendTo_s, target,
                                expect_return),
                   NS_DISPATCH_SYNC);
   }
 
   int received() const { return received_; }
 
   static void socket_readable_cb(NR_SOCKET s, int how, void *arg) {
@@ -368,67 +371,49 @@ class TurnClient : public MtransportTest
   nr_turn_client_ctx *turn_ctx_;
   std::string relay_addr_;
   bool allocated_;
   int received_;
   int protocol_;
 };
 
 TEST_F(TurnClient, Allocate) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   Allocate();
 }
 
 TEST_F(TurnClient, AllocateTcp) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   SetTcp();
   Allocate();
 }
 
 TEST_F(TurnClient, AllocateAndHold) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   Allocate();
   PR_Sleep(20000);
   ASSERT_TRUE(turn_ctx_->state == NR_TURN_CLIENT_STATE_ALLOCATED);
 }
 
 TEST_F(TurnClient, SendToSelf) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   Allocate();
   SendTo(relay_addr_);
   ASSERT_TRUE_WAIT(received() == 100, 5000);
   SendTo(relay_addr_);
   ASSERT_TRUE_WAIT(received() == 200, 1000);
 }
 
 
 TEST_F(TurnClient, SendToSelfTcp) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   SetTcp();
   Allocate();
   SendTo(relay_addr_);
   ASSERT_TRUE_WAIT(received() == 100, 5000);
   SendTo(relay_addr_);
   ASSERT_TRUE_WAIT(received() == 200, 1000);
 }
 
 TEST_F(TurnClient, PermissionDenied) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   Allocate();
   RequestPermission(relay_addr_);
   PR_Sleep(1000);
 
   /* Fake a 403 response */
   nr_turn_permission *perm;
   perm = STAILQ_FIRST(&turn_ctx_->permissions);
   ASSERT_TRUE(perm);
@@ -442,47 +427,91 @@ TEST_F(TurnClient, PermissionDenied) {
   ASSERT_TRUE(received() == 0);
 
   //TODO: We should check if we can still send to a second destination, but
   //      we would need a second TURN client as one client can only handle one
   //      allocation (maybe as part of bug 1128128 ?).
 }
 
 TEST_F(TurnClient, DeallocateReceiveFailure) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   Allocate();
   SendTo(relay_addr_);
   ASSERT_TRUE_WAIT(received() == 100, 5000);
   Deallocate();
   turn_ctx_->state = NR_TURN_CLIENT_STATE_ALLOCATED;
   SendTo(relay_addr_);
   PR_Sleep(1000);
   ASSERT_TRUE(received() == 100);
 }
 
 TEST_F(TurnClient, DeallocateReceiveFailureTcp) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   SetTcp();
   Allocate();
   SendTo(relay_addr_);
   ASSERT_TRUE_WAIT(received() == 100, 5000);
   Deallocate();
   turn_ctx_->state = NR_TURN_CLIENT_STATE_ALLOCATED;
   /* Either the connection got closed by the TURN server already, then the send
    * is going to fail, which we simply ignore. Or the connection is still alive
    * and we cand send the data, but it should not get forwarded to us. In either
    * case we should not receive more data. */
   SendTo(relay_addr_, -1);
   PR_Sleep(1000);
   ASSERT_TRUE(received() == 100);
 }
 
 TEST_F(TurnClient, AllocateDummyServer) {
-  if (WarnIfTurnNotConfigured())
-    return;
-
   turn_server_ = kDummyTurnServer;
   Allocate(false);
 }
+
+static std::string get_environment(const char *name) {
+  char *value = getenv(name);
+
+  if (!value)
+    return "";
+
+  return value;
+}
+
+int main(int argc, char **argv)
+{
+  g_turn_server = get_environment("TURN_SERVER_ADDRESS");
+  g_turn_user = get_environment("TURN_SERVER_USER");
+  g_turn_password = get_environment("TURN_SERVER_PASSWORD");
+
+  if (g_turn_server.empty() ||
+      g_turn_user.empty(),
+      g_turn_password.empty()) {
+    printf(
+        "Set TURN_SERVER_ADDRESS, TURN_SERVER_USER, and TURN_SERVER_PASSWORD\n"
+        "environment variables to run this test\n");
+    return 0;
+  }
+  {
+    nr_transport_addr addr;
+    if (nr_str_port_to_transport_addr(g_turn_server.c_str(), 3478,
+                                      IPPROTO_UDP, &addr)) {
+      printf("Invalid TURN_SERVER_ADDRESS \"%s\". Only IP numbers supported.\n",
+             g_turn_server.c_str());
+      return 0;
+    }
+  }
+  test_utils = new MtransportTestUtils();
+  NSS_NoDB_Init(nullptr);
+  NSS_SetDomesticPolicy();
+
+  // Set up the ICE registry, etc.
+  // TODO(ekr@rtfm.com): Clean up
+  std::string dummy("dummy");
+  RUN_ON_THREAD(test_utils->sts_target(),
+                WrapRunnableNM(&NrIceCtx::Create,
+                               dummy, false, false, false, false, false,
+                               NrIceCtx::ICE_POLICY_ALL),
+                NS_DISPATCH_SYNC);
+
+  // Start the tests
+  ::testing::InitGoogleTest(&argc, argv);
+
+  int rv = RUN_ALL_TESTS();
+  delete test_utils;
+  return rv;
+}
--- a/media/webrtc/signaling/test/jsep_session_unittest.cpp
+++ b/media/webrtc/signaling/test/jsep_session_unittest.cpp
@@ -30,18 +30,16 @@
 #include "signaling/src/jsep/JsepSessionImpl.h"
 #include "signaling/src/jsep/JsepTrack.h"
 
 #include "mtransport_test_utils.h"
 
 #include "FakeIPC.h"
 #include "FakeIPC.cpp"
 
-#include "TestHarness.h"
-
 namespace mozilla {
 static std::string kAEqualsCandidate("a=candidate:");
 const static size_t kNumCandidatesPerComponent = 3;
 
 class JsepSessionTestBase : public ::testing::Test
 {
 };
 
--- a/media/webrtc/signaling/test/jsep_track_unittest.cpp
+++ b/media/webrtc/signaling/test/jsep_track_unittest.cpp
@@ -17,18 +17,16 @@
 #include "signaling/src/sdp/SipccSdp.h"
 #include "signaling/src/sdp/SdpHelper.h"
 
 #include "mtransport_test_utils.h"
 
 #include "FakeIPC.h"
 #include "FakeIPC.cpp"
 
-#include "TestHarness.h"
-
 namespace mozilla {
 
 class JsepTrackTest : public ::testing::Test
 {
   public:
     JsepTrackTest() {}
 
     std::vector<JsepCodecDescription*>
--- a/media/webrtc/signaling/test/mediapipeline_unittest.cpp
+++ b/media/webrtc/signaling/test/mediapipeline_unittest.cpp
@@ -38,18 +38,16 @@
 
 #include "FakeIPC.h"
 #include "FakeIPC.cpp"
 
 #define GTEST_HAS_RTTI 0
 #include "gtest/gtest.h"
 #include "gtest_utils.h"
 
-#include "TestHarness.h"
-
 using namespace mozilla;
 MOZ_MTLOG_MODULE("mediapipeline")
 
 MtransportTestUtils *test_utils;
 
 namespace {
 
 class TransportInfo {
@@ -696,17 +694,16 @@ TEST_F(MediaPipelineTest, TestAudioSendE
   // Filter is empty, so should drop everything.
   ASSERT_EQ(0, p2_.GetAudioRtpCountReceived());
 }
 
 }  // end namespace
 
 
 int main(int argc, char **argv) {
-  ScopedXPCOM xpcom("mediapipeline_unittest");
   test_utils = new MtransportTestUtils();
   // Start the tests
   NSS_NoDB_Init(nullptr);
   NSS_SetDomesticPolicy();
   ::testing::InitGoogleTest(&argc, argv);
 
   int rv = RUN_ALL_TESTS();
   delete test_utils;
--- a/media/webrtc/signaling/test/sdp_unittests.cpp
+++ b/media/webrtc/signaling/test/sdp_unittests.cpp
@@ -42,18 +42,16 @@ extern "C" {
 #ifdef CRLF
 #undef CRLF
 #endif
 #define CRLF "\r\n"
 
 #include "FakeIPC.h"
 #include "FakeIPC.cpp"
 
-#include "TestHarness.h"
-
 using namespace mozilla;
 
 namespace test {
 
 static bool SetupGlobalThread() {
   if (!gThread) {
     nsIThread *thread;
 
@@ -4233,18 +4231,16 @@ TEST(NewSdpTestNoFixture, CheckRidSerial
     rid.Serialize(os);
     ASSERT_EQ("foo send pt=96;max-br=30000", os.str());
   }
 }
 
 } // End namespace test.
 
 int main(int argc, char **argv) {
-  ScopedXPCOM xpcom("sdp_unittests");
-
   test_utils = new MtransportTestUtils();
   NSS_NoDB_Init(nullptr);
   NSS_SetDomesticPolicy();
 
   ::testing::InitGoogleTest(&argc, argv);
   int result = RUN_ALL_TESTS();
 
   PeerConnectionCtx::Destroy();
--- a/xpcom/base/Logging.h
+++ b/xpcom/base/Logging.h
@@ -60,17 +60,22 @@ public:
 
   /**
    * Retrieves the module with the given name. If it does not already exist
    * it will be created.
    *
    * @param aName The name of the module.
    * @return A log module for the given name. This may be shared.
    */
+#if !defined(MOZILLA_XPCOMRT_API)
   static LogModule* Get(const char* aName);
+#else
+  // For simplicity, libxpcomrt doesn't supoort logging.
+  static LogModule* Get(const char* aName) { return nullptr; }
+#endif
 
   static void Init();
 
   /**
    * Indicates whether or not the given log level is enabled.
    */
   bool ShouldLog(LogLevel aLevel) const { return mLevel >= aLevel; }
 
@@ -166,19 +171,23 @@ void log_print(const PRLogModuleInfo* aM
                       LogLevel aLevel,
                       const char* aFmt, ...);
 
 inline bool log_test(const LogModule* module, LogLevel level) {
   MOZ_ASSERT(level != LogLevel::Disabled);
   return module && module->ShouldLog(level);
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
 void log_print(const LogModule* aModule,
                LogLevel aLevel,
                const char* aFmt, ...);
+#else
+inline void log_print(const LogModule* aModule, LogLevel aLevel, const char* aFmt, ...) {}
+#endif
 } // namespace detail
 
 } // namespace mozilla
 
 
 #define MOZ_LOG_TEST(_module,_level) mozilla::detail::log_test(_module, _level)
 
 // Helper macro used convert MOZ_LOG's third parameter, |_args|, from a
--- a/xpcom/base/nsDebugImpl.cpp
+++ b/xpcom/base/nsDebugImpl.cpp
@@ -328,18 +328,19 @@ NS_DebugBreak(uint32_t aSeverity, const 
 
 #  define PrintToBuffer(...) PR_sxprintf(StuffFixedBuffer, &buf, __VA_ARGS__)
 
   // Print "[PID]" or "[Desc PID]" at the beginning of the message.
   PrintToBuffer("[");
   if (sMultiprocessDescription) {
     PrintToBuffer("%s ", sMultiprocessDescription);
   }
-
+#if !defined(MOZILLA_XPCOMRT_API)
   PrintToBuffer("%d] ", base::GetCurrentProcId());
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   PrintToBuffer("%s: ", sevString);
 
   if (aStr) {
     PrintToBuffer("%s: ", aStr);
   }
   if (aExpr) {
     PrintToBuffer("'%s', ", aExpr);
@@ -375,34 +376,34 @@ NS_DebugBreak(uint32_t aSeverity, const 
     case NS_DEBUG_WARNING:
       return;
 
     case NS_DEBUG_BREAK:
       Break(buf.buffer);
       return;
 
     case NS_DEBUG_ABORT: {
-#if defined(MOZ_CRASHREPORTER)
+#if defined(MOZ_CRASHREPORTER) && !defined(MOZILLA_XPCOMRT_API)
       // Updating crash annotations in the child causes us to do IPC. This can
       // really cause trouble if we're asserting from within IPC code. So we
       // have to do without the annotations in that case.
       if (XRE_IsParentProcess()) {
         nsCString note("xpcom_runtime_abort(");
         note += buf.buffer;
         note += ")";
         CrashReporter::AppendAppNotesToCrashReport(note);
         CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("AbortMessage"),
                                            nsDependentCString(buf.buffer));
       }
 #endif  // MOZ_CRASHREPORTER
 
 #if defined(DEBUG) && defined(_WIN32)
       RealBreak();
 #endif
-#if defined(DEBUG)
+#if defined(DEBUG) && !defined(MOZILLA_XPCOMRT_API)
       nsTraceRefcnt::WalkTheStack(stderr);
 #endif
       Abort(buf.buffer);
       return;
     }
   }
 
   // Now we deal with assertions
@@ -417,21 +418,25 @@ NS_DebugBreak(uint32_t aSeverity, const 
       fprintf(stderr, "Suspending process; attach with the debugger.\n");
       kill(0, SIGSTOP);
 #else
       Break(buf.buffer);
 #endif
       return;
 
     case NS_ASSERT_STACK:
+#if !defined(MOZILLA_XPCOMRT_API)
       nsTraceRefcnt::WalkTheStack(stderr);
+#endif // !defined(MOZILLA_XPCOMRT_API)
       return;
 
     case NS_ASSERT_STACK_AND_ABORT:
+#if !defined(MOZILLA_XPCOMRT_API)
       nsTraceRefcnt::WalkTheStack(stderr);
+#endif // !defined(MOZILLA_XPCOMRT_API)
       // Fall through to abort
       MOZ_FALLTHROUGH;
 
     case NS_ASSERT_ABORT:
       Abort(buf.buffer);
       return;
 
     case NS_ASSERT_TRAP:
@@ -593,13 +598,13 @@ NS_ErrorAccordingToNSPR()
     case PR_NO_ACCESS_RIGHTS_ERROR:      return NS_ERROR_FILE_ACCESS_DENIED;
     default:                             return NS_ERROR_FAILURE;
   }
 }
 
 void
 NS_ABORT_OOM(size_t aSize)
 {
-#if defined(MOZ_CRASHREPORTER)
+#if defined(MOZ_CRASHREPORTER) && !defined(MOZILLA_XPCOMRT_API)
   CrashReporter::AnnotateOOMAllocationSize(aSize);
 #endif
   MOZ_CRASH();
 }
--- a/xpcom/base/nsIMemoryReporter.idl
+++ b/xpcom/base/nsIMemoryReporter.idl
@@ -510,17 +510,17 @@ typedef nsresult (*NonJSSizeOfTabFn)(nsP
                                      size_t* aStyleSize,
                                      size_t* aOtherSize);
 
 nsresult RegisterJSSizeOfTab(JSSizeOfTabFn aSizeOfTabFn);
 nsresult RegisterNonJSSizeOfTab(NonJSSizeOfTabFn aSizeOfTabFn);
 
 }
 
-#if defined(MOZ_DMD)
+#if defined(MOZ_DMD) && !defined(MOZILLA_XPCOMRT_API)
 #if !defined(MOZ_MEMORY)
 #error "MOZ_DMD requires MOZ_MEMORY"
 #endif
 
 #include "DMD.h"
 
 #define MOZ_REPORT(ptr)          mozilla::dmd::Report(ptr)
 #define MOZ_REPORT_ON_ALLOC(ptr) mozilla::dmd::ReportOnAlloc(ptr)
--- a/xpcom/build/FileLocation.cpp
+++ b/xpcom/build/FileLocation.cpp
@@ -1,17 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "FileLocation.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "nsZipArchive.h"
 #include "nsURLHelper.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 namespace mozilla {
 
 FileLocation::FileLocation()
 {
 }
 
 FileLocation::~FileLocation()
@@ -29,19 +31,21 @@ FileLocation::FileLocation(nsIFile* aFil
 }
 
 FileLocation::FileLocation(const FileLocation& aFile, const char* aPath)
 {
   if (aFile.IsZip()) {
     if (aFile.mBaseFile) {
       Init(aFile.mBaseFile, aFile.mPath.get());
     }
+#if !defined(MOZILLA_XPCOMRT_API)
     else {
       Init(aFile.mBaseZip, aFile.mPath.get());
     }
+#endif
     if (aPath) {
       int32_t i = mPath.RFindChar('/');
       if (kNotFound == i) {
         mPath.Truncate(0);
       } else {
         mPath.Truncate(i + 1);
       }
       mPath += aPath;
@@ -69,63 +73,73 @@ FileLocation::FileLocation(const FileLoc
       Init(aFile.mBaseFile);
     }
   }
 }
 
 void
 FileLocation::Init(nsIFile* aFile)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   mBaseZip = nullptr;
+#endif //!defined(MOZILLA_XPCOMRT_API)
   mBaseFile = aFile;
   mPath.Truncate();
 }
 
 void
 FileLocation::Init(nsIFile* aFile, const char* aPath)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   mBaseZip = nullptr;
+#endif // !defined(MOZILLA_XPCOMRT_API)
   mBaseFile = aFile;
   mPath = aPath;
 }
 
 void
 FileLocation::Init(nsZipArchive* aZip, const char* aPath)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   mBaseZip = aZip;
+#endif // !defined(MOZILLA_XPCOMRT_API)
   mBaseFile = nullptr;
   mPath = aPath;
 }
 
 void
 FileLocation::GetURIString(nsACString& aResult) const
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   if (mBaseFile) {
     net_GetURLSpecFromActualFile(mBaseFile, aResult);
   } else if (mBaseZip) {
     RefPtr<nsZipHandle> handler = mBaseZip->GetFD();
     handler->mFile.GetURIString(aResult);
   }
   if (IsZip()) {
     aResult.Insert("jar:", 0);
     aResult += "!/";
     aResult += mPath;
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 already_AddRefed<nsIFile>
 FileLocation::GetBaseFile()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   if (IsZip() && mBaseZip) {
     RefPtr<nsZipHandle> handler = mBaseZip->GetFD();
     if (handler) {
       return handler->mFile.GetBaseFile();
     }
     return nullptr;
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   nsCOMPtr<nsIFile> file = mBaseFile;
   return file.forget();
 }
 
 bool
 FileLocation::Equals(const FileLocation& aFile) const
 {
@@ -135,43 +149,47 @@ FileLocation::Equals(const FileLocation&
 
   if (mBaseFile && aFile.mBaseFile) {
     bool eq;
     return NS_SUCCEEDED(mBaseFile->Equals(aFile.mBaseFile, &eq)) && eq;
   }
 
   const FileLocation* a = this;
   const FileLocation* b = &aFile;
+#if !defined(MOZILLA_XPCOMRT_API)
   if (a->mBaseZip) {
     RefPtr<nsZipHandle> handler = a->mBaseZip->GetFD();
     a = &handler->mFile;
   }
   if (b->mBaseZip) {
     RefPtr<nsZipHandle> handler = b->mBaseZip->GetFD();
     b = &handler->mFile;
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   return a->Equals(*b);
 }
 
 nsresult
 FileLocation::GetData(Data& aData)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   if (!IsZip()) {
     return mBaseFile->OpenNSPRFileDesc(PR_RDONLY, 0444, &aData.mFd.rwget());
   }
   aData.mZip = mBaseZip;
   if (!aData.mZip) {
     aData.mZip = new nsZipArchive();
     aData.mZip->OpenArchive(mBaseFile);
   }
   aData.mItem = aData.mZip->GetItem(mPath.get());
   if (aData.mItem) {
     return NS_OK;
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
   return NS_ERROR_FILE_UNRECOGNIZED_PATH;
 }
 
 nsresult
 FileLocation::Data::GetSize(uint32_t* aResult)
 {
   if (mFd) {
     PRFileInfo64 fileInfo;
@@ -181,20 +199,22 @@ FileLocation::Data::GetSize(uint32_t* aR
 
     if (fileInfo.size > int64_t(UINT32_MAX)) {
       return NS_ERROR_FILE_TOO_BIG;
     }
 
     *aResult = fileInfo.size;
     return NS_OK;
   }
+#if !defined(MOZILLA_XPCOMRT_API)
   else if (mItem) {
     *aResult = mItem->RealSize();
     return NS_OK;
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
   return NS_ERROR_NOT_INITIALIZED;
 }
 
 nsresult
 FileLocation::Data::Copy(char* aBuf, uint32_t aLen)
 {
   if (mFd) {
     for (uint32_t totalRead = 0; totalRead < aLen;) {
@@ -202,23 +222,25 @@ FileLocation::Data::Copy(char* aBuf, uin
                              XPCOM_MIN(aLen - totalRead, uint32_t(INT32_MAX)));
       if (read < 0) {
         return NS_ErrorAccordingToNSPR();
       }
       totalRead += read;
     }
     return NS_OK;
   }
+#if !defined(MOZILLA_XPCOMRT_API)
   else if (mItem) {
     nsZipCursor cursor(mItem, mZip, reinterpret_cast<uint8_t*>(aBuf),
                        aLen, true);
     uint32_t readLen;
     cursor.Copy(&readLen);
     if (readLen != aLen) {
       nsZipArchive::sFileCorruptedReason = "FileLocation::Data: insufficient data";
       return NS_ERROR_FILE_CORRUPTED;
     }
     return NS_OK;
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
   return NS_ERROR_NOT_INITIALIZED;
 }
 
 } /* namespace mozilla */
--- a/xpcom/build/FileLocation.h
+++ b/xpcom/build/FileLocation.h
@@ -84,17 +84,21 @@ public:
    * Returns the path within the archive, when within an archive
    */
   void GetPath(nsACString& aResult) const { aResult = mPath; }
 
   /**
    * Boolean value corresponding to whether the file location is initialized
    * or not.
    */
+#if defined(MOZILLA_XPCOMRT_API)
+  explicit operator bool() const { return mBaseFile; }
+#else
   explicit operator bool() const { return mBaseFile || mBaseZip; }
+#endif // defined(MOZILLA_XPCOMRT_API)
 
   /**
    * Returns whether another FileLocation points to the same resource
    */
   bool Equals(const FileLocation& aFile) const;
 
   /**
    * Data associated with a FileLocation.
@@ -108,27 +112,31 @@ public:
     nsresult GetSize(uint32_t* aResult);
 
     /**
      * Copies the data in the given buffer
      */
     nsresult Copy(char* aBuf, uint32_t aLen);
   protected:
     friend class FileLocation;
+#if !defined(MOZILLA_XPCOMRT_API)
     nsZipItem* mItem;
+#endif // !defined(MOZILLA_XPCOMRT_API)
     RefPtr<nsZipArchive> mZip;
     mozilla::AutoFDClose mFd;
   };
 
   /**
    * Returns the data associated with the resource pointed at by the file
    * location.
    */
   nsresult GetData(Data& aData);
 private:
   nsCOMPtr<nsIFile> mBaseFile;
+#if !defined(MOZILLA_XPCOMRT_API)
   RefPtr<nsZipArchive> mBaseZip;
+#endif // !defined(MOZILLA_XPCOMRT_API)
   nsCString mPath;
 }; /* class FileLocation */
 
 } /* namespace mozilla */
 
 #endif /* mozilla_FileLocation_h */
--- a/xpcom/build/ServiceList.h
+++ b/xpcom/build/ServiceList.h
@@ -1,31 +1,34 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 // IWYU pragma: private, include "mozilla/Services.h"
 
+#if !defined(MOZILLA_XPCOMRT_API)
 #ifdef ACCESSIBILITY
 MOZ_SERVICE(AccessibilityService, nsIAccessibilityService,
             "@mozilla.org/accessibilityService;1")
 #endif
 MOZ_SERVICE(ChromeRegistryService, nsIChromeRegistry,
             "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(ToolkitChromeRegistryService, nsIToolkitChromeRegistry,
             "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(XULChromeRegistryService, nsIXULChromeRegistry,
             "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(XULOverlayProviderService, nsIXULOverlayProvider,
             "@mozilla.org/chrome/chrome-registry;1")
 MOZ_SERVICE(IOService, nsIIOService,
             "@mozilla.org/network/io-service;1")
+#endif // !defined(MOZILLA_XPCOMRT_API)
 MOZ_SERVICE(ObserverService, nsIObserverService,
             "@mozilla.org/observer-service;1")
+#if !defined(MOZILLA_XPCOMRT_API)
 MOZ_SERVICE(StringBundleService, nsIStringBundleService,
             "@mozilla.org/intl/stringbundle;1")
 MOZ_SERVICE(XPConnect, nsIXPConnect,
             "@mozilla.org/js/xpc/XPConnect;1")
 MOZ_SERVICE(InDOMUtils, inIDOMUtils,
             "@mozilla.org/inspector/dom-utils;1")
 MOZ_SERVICE(PermissionManager, nsIPermissionManager,
             "@mozilla.org/permissionmanager;1");
@@ -43,8 +46,9 @@ namespace mozilla {
 #endif
 
 MOZ_SERVICE(HistoryService, IHistory,
             "@mozilla.org/browser/history;1")
 
 #ifdef MOZ_USE_NAMESPACE
 } // namespace mozilla
 #endif
+#endif // !defined(MOZILLA_XPCOMRT_API)
--- a/xpcom/build/Services.cpp
+++ b/xpcom/build/Services.cpp
@@ -6,16 +6,17 @@
 
 #include "mozilla/Likely.h"
 #include "mozilla/Services.h"
 #include "nsComponentManager.h"
 #include "nsIObserverService.h"
 #include "nsNetCID.h"
 #include "nsObserverService.h"
 #include "nsXPCOMPrivate.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "nsIIOService.h"
 #include "nsIDirectoryService.h"
 #ifdef ACCESSIBILITY
 #include "nsIAccessibilityService.h"
 #endif
 #include "nsIChromeRegistry.h"
 #include "nsIStringBundle.h"
 #include "nsIToolkitChromeRegistry.h"
@@ -23,16 +24,17 @@
 #include "IHistory.h"
 #include "nsIXPConnect.h"
 #include "inIDOMUtils.h"
 #include "nsIPermissionManager.h"
 #include "nsIServiceWorkerManager.h"
 #include "nsIAsyncShutdown.h"
 #include "nsIUUIDGenerator.h"
 #include "nsIGfxInfo.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 using namespace mozilla;
 using namespace mozilla::services;
 
 /*
  * Define a global variable and a getter for every service in ServiceList.
  * eg. gIOService and GetIOService()
  */
--- a/xpcom/components/ManifestParser.h
+++ b/xpcom/components/ManifestParser.h
@@ -3,17 +3,19 @@
 /* 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/. */
 
 #ifndef ManifestParser_h
 #define ManifestParser_h
 
 #include "nsComponentManager.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "nsChromeRegistry.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/FileLocation.h"
 
 void ParseManifest(NSLocationType aType, mozilla::FileLocation& aFile,
                    char* aBuf, bool aChromeOnly, bool aXPTOnly = false);
 
 void LogMessage(const char* aMsg, ...);
 
 void LogMessageWithContext(mozilla::FileLocation& aFile,
--- a/xpcom/components/nsCategoryManager.cpp
+++ b/xpcom/components/nsCategoryManager.cpp
@@ -413,17 +413,19 @@ nsCategoryManager::nsCategoryManager()
 {
   PL_INIT_ARENA_POOL(&mArena, "CategoryManagerArena",
                      NS_CATEGORYMANAGER_ARENA_SIZE);
 }
 
 void
 nsCategoryManager::InitMemoryReporter()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   RegisterStrongMemoryReporter(this);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 nsCategoryManager::~nsCategoryManager()
 {
   // the hashtable contains entries that must be deleted before the arena is
   // destroyed, or else you will have PRLocks undestroyed and other Really
   // Bad Stuff (TM)
   mTable.Clear();
@@ -798,25 +800,29 @@ NS_CreateServicesFromCategory(const char
     rv = categoryManager->GetCategoryEntry(aCategory, entryString.get(),
                                            getter_Copies(contractID));
     if (NS_FAILED(rv)) {
       continue;
     }
 
     nsCOMPtr<nsISupports> instance = do_GetService(contractID);
     if (!instance) {
+#if !defined(MOZILLA_XPCOMRT_API)
       LogMessage("While creating services from category '%s', could not create service for entry '%s', contract ID '%s'",
                  aCategory, entryString.get(), contractID.get());
+#endif // !defined(MOZILLA_XPCOMRT_API)
       continue;
     }
 
     if (aObserverTopic) {
       // try an observer, if it implements it.
       nsCOMPtr<nsIObserver> observer = do_QueryInterface(instance);
       if (observer) {
         observer->Observe(aOrigin, aObserverTopic, EmptyString().get());
       } else {
+#if !defined(MOZILLA_XPCOMRT_API)
         LogMessage("While creating services from category '%s', service for entry '%s', contract ID '%s' does not implement nsIObserver.",
                    aCategory, entryString.get(), contractID.get());
+#endif // !defined(MOZILLA_XPCOMRT_API)
       }
     }
   }
 }
--- a/xpcom/components/nsComponentManager.cpp
+++ b/xpcom/components/nsComponentManager.cpp
@@ -53,18 +53,20 @@
 #include "nsXPIDLString.h"
 #include "prcmon.h"
 #include "xptinfo.h" // this after nsISupports, to pick up IID so that xpt stuff doesn't try to define it itself...
 #include "nsThreadUtils.h"
 #include "prthread.h"
 #include "private/pprthred.h"
 #include "nsTArray.h"
 #include "prio.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "ManifestParser.h"
 #include "nsNetUtil.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/Services.h"
 
 #include "mozilla/GenericFactory.h"
 #include "nsSupportsPrimitives.h"
 #include "nsArray.h"
 #include "nsIMutableArray.h"
 #include "nsArrayEnumerator.h"
 #include "nsStringEnumerator.h"
@@ -247,16 +249,17 @@ public:
 
 private:
   SafeMutex& mMutex;
   bool mLocked;
 };
 
 } // namespace
 
+#if !defined(MOZILLA_XPCOMRT_API)
 // this is safe to call during InitXPCOM
 static already_AddRefed<nsIFile>
 GetLocationFromDirectoryService(const char* aProp)
 {
   nsCOMPtr<nsIProperties> directoryService;
   nsDirectoryService::Create(nullptr,
                              NS_GET_IID(nsIProperties),
                              getter_AddRefs(directoryService));
@@ -283,16 +286,17 @@ CloneAndAppend(nsIFile* aBase, const nsA
   aBase->Clone(getter_AddRefs(f));
   if (!f) {
     return nullptr;
   }
 
   f->AppendNative(aAppend);
   return f.forget();
 }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 ////////////////////////////////////////////////////////////////////////////////
 // nsComponentManagerImpl
 ////////////////////////////////////////////////////////////////////////////////
 
 nsresult
 nsComponentManagerImpl::Create(nsISupports* aOuter, REFNSIID aIID,
                                void** aResult)
@@ -315,39 +319,43 @@ nsComponentManagerImpl::nsComponentManag
   , mContractIDs(CONTRACTID_HASHTABLE_INITIAL_LENGTH)
   , mLock("nsComponentManagerImpl.mLock")
   , mStatus(NOT_INITIALIZED)
 {
 }
 
 nsTArray<const mozilla::Module*>* nsComponentManagerImpl::sStaticModules;
 
+#if !defined(MOZILLA_XPCOMRT_API)
 NSMODULE_DEFN(start_kPStaticModules);
 NSMODULE_DEFN(end_kPStaticModules);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 /* The content between start_kPStaticModules and end_kPStaticModules is gathered
  * by the linker from various objects containing symbols in a specific section.
  * ASAN considers (rightfully) the use of this content as a global buffer
  * overflow. But this is a deliberate and well-considered choice, with no proper
  * way to make ASAN happy. */
 MOZ_ASAN_BLACKLIST
 /* static */ void
 nsComponentManagerImpl::InitializeStaticModules()
 {
   if (sStaticModules) {
     return;
   }
 
   sStaticModules = new nsTArray<const mozilla::Module*>;
+#if !defined(MOZILLA_XPCOMRT_API)
   for (const mozilla::Module * const* staticModules =
          &NSMODULE_NAME(start_kPStaticModules) + 1;
        staticModules < &NSMODULE_NAME(end_kPStaticModules); ++staticModules)
     if (*staticModules) { // ASAN adds padding
       sStaticModules->AppendElement(*staticModules);
     }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 nsTArray<nsComponentManagerImpl::ComponentLocation>*
 nsComponentManagerImpl::sModuleLocations;
 
 /* static */ void
 nsComponentManagerImpl::InitializeModuleLocations()
 {
@@ -361,36 +369,47 @@ nsComponentManagerImpl::InitializeModule
 nsresult
 nsComponentManagerImpl::Init()
 {
   PR_ASSERT(NOT_INITIALIZED == mStatus);
 
   // Initialize our arena
   PL_INIT_ARENA_POOL(&mArena, "ComponentManagerArena", NS_CM_BLOCK_SIZE);
 
+#if !defined(MOZILLA_XPCOMRT_API)
   nsCOMPtr<nsIFile> greDir =
     GetLocationFromDirectoryService(NS_GRE_DIR);
   nsCOMPtr<nsIFile> appDir =
     GetLocationFromDirectoryService(NS_XPCOM_CURRENT_PROCESS_DIR);
+#endif
 
   InitializeStaticModules();
 
+#if !defined(MOZILLA_XPCOMRT_API)
   nsresult rv = mNativeModuleLoader.Init();
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   nsCategoryManager::GetSingleton()->SuppressNotifications(true);
+#endif
 
+#if defined(MOZILLA_XPCOMRT_API)
+  RegisterModule(&kXPCOMRTModule, nullptr);
+  RegisterModule(&kNeckoStandaloneModule, nullptr);
+  RegisterModule(&kStunUDPSocketFilterHandlerModule, nullptr);
+#else
   RegisterModule(&kXPCOMModule, nullptr);
+#endif // defined(MOZILLA_XPCOMRT_API)
 
   for (uint32_t i = 0; i < sStaticModules->Length(); ++i) {
     RegisterModule((*sStaticModules)[i], nullptr);
   }
 
+#if !defined(MOZILLA_XPCOMRT_API)
   // The overall order in which chrome.manifests are expected to be treated
   // is the following:
   // - greDir
   // - greDir's omni.ja
   // - appDir
   // - appDir's omni.ja
 
   InitializeModuleLocations();
@@ -439,16 +458,17 @@ nsComponentManagerImpl::Init()
   // We can't initialize the preference watcher when the log module manager is
   // initialized, as a number of things attempt to start logging before the
   // preference system is initialized.
   //
   // The preference system is registered as a component so at this point during
   // component manager initialization we know it is setup and we can register
   // for notifications.
   LogModulePrefWatcher::RegisterPrefWatcher();
+#endif
 
   // Unfortunately, we can't register the nsCategoryManager memory reporter
   // in its constructor (which is triggered by the GetSingleton() call
   // above) because the memory reporter manager isn't initialized at that
   // point.  So we wait until now.
   nsCategoryManager::GetSingleton()->InitMemoryReporter();
 
   MOZ_LOG(nsComponentManagerLog, LogLevel::Debug,
@@ -547,20 +567,22 @@ nsComponentManagerImpl::RegisterCIDEntry
 
     nsCString existing;
     if (f->mModule) {
       existing = f->mModule->Description();
     } else {
       existing = "<unknown module>";
     }
     SafeMutexAutoUnlock unlock(mLock);
+#if !defined(MOZILLA_XPCOMRT_API)
     LogMessage("While registering XPCOM module %s, trying to re-register CID '%s' already registered by %s.",
                aModule->Description().get(),
                idstr,
                existing.get());
+#endif // !defined(MOZILLA_XPCOMRT_API)
     return;
   }
 
   f = new nsFactoryEntry(aEntry, aModule);
   mFactories.Put(*aEntry->cid, f);
 }
 
 void
@@ -576,26 +598,29 @@ nsComponentManagerImpl::RegisterContract
   nsFactoryEntry* f = mFactories.Get(*aEntry->cid);
   if (!f) {
     NS_WARNING("No CID found when attempting to map contract ID");
 
     char idstr[NSID_LENGTH];
     aEntry->cid->ToProvidedString(idstr);
 
     SafeMutexAutoUnlock unlock(mLock);
+#if !defined(MOZILLA_XPCOMRT_API)
     LogMessage("Could not map contract ID '%s' to CID %s because no implementation of the CID is registered.",
                aEntry->contractid,
                idstr);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
     return;
   }
 
   mContractIDs.Put(nsDependentCString(aEntry->contractid), f);
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
 static void
 CutExtension(nsCString& aPath)
 {
   int32_t dotPos = aPath.RFindChar('.');
   if (kNotFound == dotPos) {
     aPath.Truncate();
   } else {
     aPath.Cut(0, dotPos + 1);
@@ -828,27 +853,30 @@ nsComponentManagerImpl::ManifestCategory
 void
 nsComponentManagerImpl::RereadChromeManifests(bool aChromeOnly)
 {
   for (uint32_t i = 0; i < sModuleLocations->Length(); ++i) {
     ComponentLocation& l = sModuleLocations->ElementAt(i);
     RegisterManifest(l.type, l.location, aChromeOnly);
   }
 }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 bool
 nsComponentManagerImpl::KnownModule::EnsureLoader()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   if (!mLoader) {
     nsCString extension;
     mFile.GetURIString(extension);
     CutExtension(extension);
     mLoader =
       nsComponentManagerImpl::gComponentManager->LoaderForExtension(extension);
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
   return !!mLoader;
 }
 
 bool
 nsComponentManagerImpl::KnownModule::Load()
 {
   if (mFailed) {
     return false;
@@ -895,34 +923,38 @@ nsresult nsComponentManagerImpl::Shutdow
   PR_ASSERT(NORMAL == mStatus);
 
   mStatus = SHUTDOWN_IN_PROGRESS;
 
   // Shutdown the component manager
   MOZ_LOG(nsComponentManagerLog, LogLevel::Debug,
          ("nsComponentManager: Beginning Shutdown."));
 
+#if !defined(MOZILLA_XPCOMRT_API)
   UnregisterWeakMemoryReporter(this);
+#endif
 
   // Release all cached factories
   mContractIDs.Clear();
   mFactories.Clear(); // XXX release the objects, don't just clear
   mLoaderMap.Clear();
   mKnownModules.Clear();
   mKnownStaticModules.Clear();
 
   delete sStaticModules;
   delete sModuleLocations;
 #ifdef MOZ_B2G_LOADER
   delete sXPTIInfosBook;
   sXPTIInfosBook = nullptr;
 #endif
 
+#if !defined(MOZILLA_XPCOMRT_API)
   // Unload libraries
   mNativeModuleLoader.UnloadLibraries();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   // delete arena for strings and small objects
   PL_FinishArenaPool(&mArena);
 
   mStatus = SHUTDOWN_COMPLETE;
 
   MOZ_LOG(nsComponentManagerLog, LogLevel::Debug,
          ("nsComponentManager: Shutdown complete."));
@@ -1583,32 +1615,34 @@ nsComponentManagerImpl::GetServiceByCont
 
   nsISupports** sresult = reinterpret_cast<nsISupports**>(aResult);
   *sresult = entry->mServiceObject;
   (*sresult)->AddRef();
 
   return NS_OK;
 }
 
+#if !defined(MOZILLA_XPCOMRT_API)
 already_AddRefed<mozilla::ModuleLoader>
 nsComponentManagerImpl::LoaderForExtension(const nsACString& aExt)
 {
   nsCOMPtr<mozilla::ModuleLoader> loader = mLoaderMap.Get(aExt);
   if (!loader) {
     loader = do_GetServiceFromCategory("module-loader",
                                        PromiseFlatCString(aExt).get());
     if (!loader) {
       return nullptr;
     }
 
     mLoaderMap.Put(aExt, loader);
   }
 
   return loader.forget();
 }
+#endif
 
 NS_IMETHODIMP
 nsComponentManagerImpl::RegisterFactory(const nsCID& aClass,
                                         const char* aName,
                                         const char* aContractID,
                                         nsIFactory* aFactory)
 {
   if (!aFactory) {
@@ -1671,18 +1705,22 @@ nsComponentManagerImpl::UnregisterFactor
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::AutoRegister(nsIFile* aLocation)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   XRE_AddManifestLocation(NS_EXTENSION_LOCATION, aLocation);
   return NS_OK;
+#else
+  return NS_ERROR_NOT_IMPLEMENTED;
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::AutoUnregister(nsIFile* aLocation)
 {
   NS_ERROR("AutoUnregister not implemented.");
   return NS_ERROR_NOT_IMPLEMENTED;
 }
@@ -1990,34 +2028,39 @@ XRE_AddStaticComponent(const mozilla::Mo
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::AddBootstrappedManifestLocation(nsIFile* aLocation)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   nsString path;
   nsresult rv = aLocation->GetPath(path);
   if (NS_FAILED(rv)) {
     return rv;
   }
 
   if (Substring(path, path.Length() - 4).EqualsLiteral(".xpi")) {
     return XRE_AddJarManifestLocation(NS_BOOTSTRAPPED_LOCATION, aLocation);
   }
 
   nsCOMPtr<nsIFile> manifest =
     CloneAndAppend(aLocation, NS_LITERAL_CSTRING("chrome.manifest"));
   return XRE_AddManifestLocation(NS_BOOTSTRAPPED_LOCATION, manifest);
+#else
+  return NS_ERROR_NOT_IMPLEMENTED;
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::RemoveBootstrappedManifestLocation(nsIFile* aLocation)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   nsCOMPtr<nsIChromeRegistry> cr = mozilla::services::GetChromeRegistryService();
   if (!cr) {
     return NS_ERROR_FAILURE;
   }
 
   nsCOMPtr<nsIFile> manifest;
   nsString path;
   nsresult rv = aLocation->GetPath(path);
@@ -2037,21 +2080,25 @@ nsComponentManagerImpl::RemoveBootstrapp
   }
 
   // Remove reference.
   nsComponentManagerImpl::sModuleLocations->RemoveElement(elem,
                                                           ComponentLocationComparator());
 
   rv = cr->CheckForNewChrome();
   return rv;
+#else
+  return NS_ERROR_NOT_IMPLEMENTED;
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 NS_IMETHODIMP
 nsComponentManagerImpl::GetManifestLocations(nsIArray** aLocations)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   NS_ENSURE_ARG_POINTER(aLocations);
   *aLocations = nullptr;
 
   if (!sModuleLocations) {
     return NS_ERROR_NOT_INITIALIZED;
   }
 
   nsCOMPtr<nsIMutableArray> locations = nsArray::Create();
@@ -2065,16 +2112,19 @@ nsComponentManagerImpl::GetManifestLocat
     rv = NS_NewURI(getter_AddRefs(uri), uriString);
     if (NS_SUCCEEDED(rv)) {
       locations->AppendElement(uri, false);
     }
   }
 
   locations.forget(aLocations);
   return NS_OK;
+#else
+  return NS_ERROR_NOT_IMPLEMENTED;
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 #ifdef MOZ_B2G_LOADER
 
 /* static */
 void
 nsComponentManagerImpl::XPTOnlyManifestManifest(
     XPTOnlyManifestProcessingContext&  aCx, int aLineNo, char* const* aArgv)
@@ -2113,16 +2163,17 @@ nsComponentManagerImpl::PreloadXPT(nsIFi
 void
 PreloadXPT(nsIFile* aOmnijarFile)
 {
   nsComponentManagerImpl::PreloadXPT(aOmnijarFile);
 }
 
 #endif /* MOZ_B2G_LOADER */
 
+#if !defined(MOZILLA_XPCOMRT_API)
 EXPORT_XPCOM_API(nsresult)
 XRE_AddManifestLocation(NSLocationType aType, nsIFile* aLocation)
 {
   nsComponentManagerImpl::InitializeModuleLocations();
   nsComponentManagerImpl::ComponentLocation* c =
     nsComponentManagerImpl::sModuleLocations->AppendElement();
   c->type = aType;
   c->location.Init(aLocation);
@@ -2153,9 +2204,10 @@ XRE_AddJarManifestLocation(NSLocationTyp
         nsComponentManagerImpl::gComponentManager->mStatus) {
     nsComponentManagerImpl::gComponentManager->RegisterManifest(aType,
                                                                 c->location,
                                                                 false);
   }
 
   return NS_OK;
 }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
--- a/xpcom/components/nsComponentManager.h
+++ b/xpcom/components/nsComponentManager.h
@@ -64,17 +64,23 @@ extern const char fileSizeValueName[];
 extern const char nativeComponentType[];
 extern const char staticComponentType[];
 
 #ifdef DEBUG
 #define XPCOM_CHECK_PENDING_CIDS
 #endif
 ////////////////////////////////////////////////////////////////////////////////
 
+#if defined(MOZILLA_XPCOMRT_API)
+extern const mozilla::Module kXPCOMRTModule;
+extern const mozilla::Module kNeckoStandaloneModule;
+extern const mozilla::Module kStunUDPSocketFilterHandlerModule;
+#else
 extern const mozilla::Module kXPCOMModule;
+#endif
 
 /**
  * This is a wrapper around mozilla::Mutex which provides runtime
  * checking for a deadlock where the same thread tries to lock a mutex while
  * it is already locked. This checking is present in both debug and release
  * builds.
  */
 class SafeMutex
--- a/xpcom/ds/nsObserverService.cpp
+++ b/xpcom/ds/nsObserverService.cpp
@@ -167,23 +167,27 @@ nsObserverService::nsObserverService()
 nsObserverService::~nsObserverService(void)
 {
   Shutdown();
 }
 
 void
 nsObserverService::RegisterReporter()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   RegisterWeakMemoryReporter(this);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 void
 nsObserverService::Shutdown()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   UnregisterWeakMemoryReporter(this);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   mShuttingDown = true;
 
   mObserverTopicTable.Clear();
 }
 
 nsresult
 nsObserverService::Create(nsISupports* aOuter, const nsIID& aIID,
@@ -313,22 +317,24 @@ NS_IMETHODIMP nsObserverService::NotifyO
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsObserverService::UnmarkGrayStrongObservers()
 {
   NS_ENSURE_VALIDCALL
 
+#if !defined(MOZILLA_XPCOMRT_API)
   nsCOMArray<nsIObserver> strongObservers;
   for (auto iter = mObserverTopicTable.Iter(); !iter.Done(); iter.Next()) {
     nsObserverList* aObserverList = iter.Get();
     if (aObserverList) {
       aObserverList->AppendStrongObservers(strongObservers);
     }
   }
 
   for (uint32_t i = 0; i < strongObservers.Length(); ++i) {
     xpc_TryUnmarkWrappedGrayObject(strongObservers[i]);
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   return NS_OK;
 }
--- a/xpcom/glue/BlockingResourceBase.cpp
+++ b/xpcom/glue/BlockingResourceBase.cpp
@@ -18,17 +18,17 @@
 #include "nsTHashtable.h"
 #endif
 
 #include "mozilla/CondVar.h"
 #include "mozilla/DeadlockDetector.h"
 #include "mozilla/ReentrantMonitor.h"
 #include "mozilla/Mutex.h"
 
-#if defined(MOZILLA_INTERNAL_API)
+#if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_XPCOMRT_API)
 #include "GeckoProfiler.h"
 #endif //MOZILLA_INTERNAL_API
 
 #endif // ifdef DEBUG
 
 namespace mozilla {
 //
 // BlockingResourceBase implementation
@@ -456,26 +456,26 @@ ReentrantMonitor::Wait(PRIntervalTime aI
   int32_t savedEntryCount = mEntryCount;
   AcquisitionState savedAcquisitionState = GetAcquisitionState();
   BlockingResourceBase* savedChainPrev = mChainPrev;
   mEntryCount = 0;
   ClearAcquisitionState();
   mChainPrev = 0;
 
   nsresult rv;
-#if defined(MOZILLA_INTERNAL_API)
+#if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_XPCOMRT_API)
   {
     GeckoProfilerSleepRAII profiler_sleep;
 #endif //MOZILLA_INTERNAL_API
 
     // give up the monitor until we're back from Wait()
     rv = PR_Wait(mReentrantMonitor, aInterval) == PR_SUCCESS ? NS_OK :
                                                                NS_ERROR_FAILURE;
 
-#if defined(MOZILLA_INTERNAL_API)
+#if defined(MOZILLA_INTERNAL_API) && !defined(MOZILLA_XPCOMRT_API)
   }
 #endif //MOZILLA_INTERNAL_API
 
   // restore saved state
   mEntryCount = savedEntryCount;
   SetAcquisitionState(savedAcquisitionState);
   mChainPrev = savedChainPrev;
 
--- a/xpcom/glue/nsISupportsImpl.h
+++ b/xpcom/glue/nsISupportsImpl.h
@@ -123,17 +123,17 @@ private:
 #define NS_ASSERT_OWNINGTHREAD_AGGREGATE(agg, _class) ((void)0)
 #define NS_ASSERT_OWNINGTHREAD(_class)  ((void)0)
 
 #endif // DEBUG || (NIGHTLY_BUILD && !MOZ_PROFILING)
 
 
 // Macros for reference-count and constructor logging
 
-#if defined(NS_BUILD_REFCNT_LOGGING)
+#if defined(NS_BUILD_REFCNT_LOGGING) && !defined(MOZILLA_XPCOMRT_API)
 
 #define NS_LOG_ADDREF(_p, _rc, _type, _size) \
   NS_LogAddRef((_p), (_rc), (_type), (uint32_t) (_size))
 
 #define NS_LOG_RELEASE(_p, _rc, _type) \
   NS_LogRelease((_p), (_rc), (_type))
 
 #include "mozilla/TypeTraits.h"
new file mode 100644
--- /dev/null
+++ b/xpcom/libxpcomrt/XPCOMRTInit.cpp
@@ -0,0 +1,199 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 ci et: */
+/* 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/. */
+
+#include "mozilla/Module.h"
+#include "mozilla/ModuleUtils.h"
+#include "mozilla/NullPtr.h"
+#include "mozilla/TimeStamp.h"
+#include "nsCategoryManager.h"
+#include "nsComponentManager.h"
+#include "nsDebugImpl.h"
+#include "nsIErrorService.h"
+#include "nsMemoryImpl.h"
+#include "nsNetCID.h"
+#include "nsNetModuleStandalone.h"
+#include "nsObserverService.h"
+#include "nsThreadManager.h"
+#include "nsThreadPool.h"
+#include "nsUUIDGenerator.h"
+#include "nsXPCOMCIDInternal.h"
+#include "nsXPCOMPrivate.h"
+#include "TimerThread.h"
+#include "XPCOMRTInit.h"
+
+static NS_DEFINE_CID(kComponentManagerCID, NS_COMPONENTMANAGER_CID);
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsTimerImpl)
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsUUIDGenerator, Init)
+
+static nsresult
+nsThreadManagerGetSingleton(nsISupports* aOuter,
+                            const nsIID& aIID,
+                            void** aInstancePtr)
+{
+  NS_ASSERTION(aInstancePtr, "null outptr");
+  if (NS_WARN_IF(aOuter)) {
+    return NS_ERROR_NO_AGGREGATION;
+  }
+
+  return nsThreadManager::get()->QueryInterface(aIID, aInstancePtr);
+}
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsThreadPool)
+
+nsComponentManagerImpl* nsComponentManagerImpl::gComponentManager = nullptr;
+bool gXPCOMShuttingDown = false;
+bool gXPCOMThreadsShutDown = false;
+
+#define COMPONENT(NAME, Ctor) static NS_DEFINE_CID(kNS_##NAME##_CID, NS_##NAME##_CID);
+#include "XPCOMRTModule.inc"
+#undef COMPONENT
+
+#define COMPONENT(NAME, Ctor) { &kNS_##NAME##_CID, false, nullptr, Ctor },
+const mozilla::Module::CIDEntry kXPCOMCIDEntries[] = {
+  { &kComponentManagerCID, true, nullptr, nsComponentManagerImpl::Create },
+#include "XPCOMRTModule.inc"
+  { nullptr }
+};
+#undef COMPONENT
+
+#define COMPONENT(NAME, Ctor) { NS_##NAME##_CONTRACTID, &kNS_##NAME##_CID },
+const mozilla::Module::ContractIDEntry kXPCOMContracts[] = {
+#include "XPCOMRTModule.inc"
+  { nullptr }
+};
+#undef COMPONENT
+
+const mozilla::Module kXPCOMRTModule = {
+  mozilla::Module::kVersion, kXPCOMCIDEntries, kXPCOMContracts
+};
+
+nsresult
+NS_InitXPCOMRT()
+{
+  nsresult rv = NS_OK;
+
+  NS_SetMainThread();
+
+  mozilla::TimeStamp::Startup();
+
+  rv = nsThreadManager::get()->Init();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  // Set up the timer globals/timer thread
+  rv = nsTimerImpl::Startup();
+  if (NS_WARN_IF(NS_FAILED(rv))) {
+    return rv;
+  }
+
+  nsComponentManagerImpl::gComponentManager = new nsComponentManagerImpl();
+  NS_ADDREF(nsComponentManagerImpl::gComponentManager);
+
+  rv = nsComponentManagerImpl::gComponentManager->Init();
+  if (NS_FAILED(rv)) {
+    NS_RELEASE(nsComponentManagerImpl::gComponentManager);
+    return rv;
+  }
+
+  mozilla::InitNetModuleStandalone();
+
+  return NS_OK;
+}
+
+nsresult
+NS_ShutdownXPCOMRT()
+{
+  nsresult rv = NS_OK;
+
+  // Notify observers of xpcom shutting down
+  {
+    // Block it so that the COMPtr will get deleted before we hit
+    // servicemanager shutdown
+
+    nsCOMPtr<nsIThread> thread = do_GetCurrentThread();
+
+    if (NS_WARN_IF(!thread)) {
+      return NS_ERROR_UNEXPECTED;
+    }
+
+    RefPtr<nsObserverService> observerService;
+    CallGetService("@mozilla.org/observer-service;1",
+                     (nsObserverService**)getter_AddRefs(observerService));
+
+    if (observerService) {
+      observerService->NotifyObservers(nullptr,
+                                       NS_XPCOM_WILL_SHUTDOWN_OBSERVER_ID,
+                                       nullptr);
+
+      nsCOMPtr<nsIServiceManager> mgr;
+      rv = NS_GetServiceManager(getter_AddRefs(mgr));
+      if (NS_SUCCEEDED(rv)) {
+        observerService->NotifyObservers(mgr, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
+                                         nullptr);
+      }
+    }
+
+    // This must happen after the shutdown of media and widgets, which
+    // are triggered by the NS_XPCOM_SHUTDOWN_OBSERVER_ID notification.
+    NS_ProcessPendingEvents(thread);
+
+    if (observerService)
+      observerService->NotifyObservers(nullptr,
+                                       NS_XPCOM_SHUTDOWN_THREADS_OBSERVER_ID,
+                                       nullptr);
+
+    gXPCOMThreadsShutDown = true;
+    NS_ProcessPendingEvents(thread);
+
+    // Shutdown the timer thread and all timers that might still be alive before
+    // shutting down the component manager
+    nsTimerImpl::Shutdown();
+
+    NS_ProcessPendingEvents(thread);
+
+    // Net module needs to be shutdown before the thread manager or else
+    // the thread manager will hang waiting for the socket transport
+    // service to shutdown.
+    mozilla::ShutdownNetModuleStandalone();
+
+    // Shutdown all remaining threads.  This method does not return until
+    // all threads created using the thread manager (with the exception of
+    // the main thread) have exited.
+    nsThreadManager::get()->Shutdown();
+
+    NS_ProcessPendingEvents(thread);
+  }
+
+  mozilla::services::Shutdown();
+
+  // Shutdown global servicemanager
+  if (nsComponentManagerImpl::gComponentManager) {
+    nsComponentManagerImpl::gComponentManager->FreeServices();
+  }
+
+  // Shutdown xpcom. This will release all loaders and cause others holding
+  // a refcount to the component manager to release it.
+  if (nsComponentManagerImpl::gComponentManager) {
+    rv = (nsComponentManagerImpl::gComponentManager)->Shutdown();
+    NS_ASSERTION(NS_SUCCEEDED(rv), "Component Manager shutdown failed.");
+  } else {
+    NS_WARNING("Component Manager was never created ...");
+  }
+
+  // Finally, release the component manager last because it unloads the
+  // libraries:
+  if (nsComponentManagerImpl::gComponentManager) {
+    nsrefcnt cnt;
+    NS_RELEASE2(nsComponentManagerImpl::gComponentManager, cnt);
+    NS_ASSERTION(cnt == 0, "Component Manager being held past XPCOM shutdown.");
+  }
+  nsComponentManagerImpl::gComponentManager = nullptr;
+  nsCategoryManager::Destroy();
+
+  return NS_OK;
+}
new file mode 100644
--- /dev/null
+++ b/xpcom/libxpcomrt/XPCOMRTInit.h
@@ -0,0 +1,15 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 ci et: */
+/* 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/. */
+
+#ifndef XPCOMRT_INIT_H__
+#define XPCOMRT_INIT_H__
+
+#include "nsError.h"
+
+nsresult NS_InitXPCOMRT();
+nsresult NS_ShutdownXPCOMRT();
+
+#endif // define XPCOMRT_INIT_H__
new file mode 100644
--- /dev/null
+++ b/xpcom/libxpcomrt/XPCOMRTModule.inc
@@ -0,0 +1,8 @@
+    COMPONENT(MEMORY, nsMemoryImpl::Create)
+    COMPONENT(DEBUG,  nsDebugImpl::Create)
+    COMPONENT(CATEGORYMANAGER, nsCategoryManager::Create)
+    COMPONENT(OBSERVERSERVICE, nsObserverService::Create)
+    COMPONENT(TIMER, nsTimerImplConstructor)
+    COMPONENT(THREADMANAGER, nsThreadManagerGetSingleton)
+    COMPONENT(THREADPOOL, nsThreadPoolConstructor)
+    COMPONENT(UUID_GENERATOR, nsUUIDGeneratorConstructor)
new file mode 100644
--- /dev/null
+++ b/xpcom/libxpcomrt/XPCOMRTStubs.cpp
@@ -0,0 +1,65 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim:set ts=4 sw=4 sts=4 ci et: */
+/* 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/. */
+
+#include "nsXULAppAPI.h"
+#include "mozilla/TimeStamp.h"
+
+
+GeckoProcessType
+XRE_GetProcessType()
+{
+  return GeckoProcessType_Default;
+}
+
+bool
+XRE_IsParentProcess()
+{
+  return XRE_GetProcessType() == GeckoProcessType_Default;
+}
+
+bool
+XRE_IsContentProcess()
+{
+  return XRE_GetProcessType() == GeckoProcessType_Content;
+}
+
+#define PRINT_CALLED fprintf(stderr, "!!! ERROR: function %s defined in file %s should not be called, needs to be correctly implemented.\n", __FUNCTION__, __FILE__)
+
+class nsAString;
+class nsCString;
+
+namespace base {
+  class Histogram;
+} // namespace base
+
+namespace mozilla {
+namespace Telemetry {
+
+#include "mozilla/TelemetryHistogramEnums.h"
+
+void Accumulate(ID id, uint32_t sample) {}
+void Accumulate(ID id, const nsCString& key, uint32_t sample) {}
+void Accumulate(const char* name, uint32_t sample) {}
+void AccumulateTimeDelta(ID id, TimeStamp start, TimeStamp end) {}
+
+base::Histogram* GetHistogramById(ID id)
+{
+  return nullptr;
+}
+
+base::Histogram* GetKeyedHistogramById(ID id, const nsAString&)
+{
+  return nullptr;
+}
+
+} // namespace Telemetry
+
+namespace detail {
+
+void log_print(const PRLogModuleInfo* aModule, LogLevel aLevel, const char* aFmt, ...) {}
+
+} // namespace detail
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/xpcom/libxpcomrt/docs/index.rst
@@ -0,0 +1,40 @@
+==========================
+ XPCOM Standalone Library
+==========================
+
+What it is for
+--------------
+The XPCOM standalone library, libxpcomrt, was created to support building the WebRTC
+standalone library. The libxpcomrt library contains only the parts of XPCOM that are required
+to run WebRTC; parts such as the cycle collector and the startup cache required only by Gecko
+are not included. A library containing a small subset of Necko was also
+created to support the WebRTC standalone library.
+
+The libxcomrt library was created specifically to support the WebRTC standalone library.
+It is not intended to be used as a general purpose library to add XPCOM functionality to
+an application. It is likely that some of the code contained in the libxpcomrt library
+has unresolved symbols that may be exposed if used for purposes other than being linked
+into the WebRTC standalone library.
+
+How to use it
+-------------
+When compiling code utilizing libxpcomrt, both ``MOZILLA_INTERNAL_API`` and ``MOZILLA_XPCOMRT_API``
+must be defined in addition to whatever standard flags are used to compile Gecko.
+The library is initialized with ``NS_InitXPCOMRT()`` and shutdown with ``NS_ShutdownXPCOMRT()``.
+Both functions are declared in xpcom/libxpcomrt/XPCOMRTInit.h.
+Only a small number of services which are required for the WebRTC
+standalone library to function are included with libxpcomrt. The dynamic loading of services is not
+supported. Including a service through ``NSMODULE_DEFN`` and static linking is also not supported.
+The only way to add a service to libxpcomrt is to explicitly start the service during
+``nsComponentManagerImpl::Init`` in xpcom/components/nsComponentManager.cpp.
+The best method to determine what parts of XPCOM are included in libxpcomrt is to examine the
+xpcom/libxpcomrt/moz.build file. It contains all of the XPCOM source files used to build libxpcomrt.
+A few of the services that are included are:
+
+* UUID Generator
+* DNS Service
+* Socket Transport Service
+* IDN Service
+
+All dependencies on ipc/chromium have been removed.
+IO and preference services are not included making this library of limited utility.
new file mode 100644
--- /dev/null
+++ b/xpcom/libxpcomrt/moz.build
@@ -0,0 +1,142 @@
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+if CONFIG['OS_TARGET'] != 'WINNT' and CONFIG['MOZ_WIDGET_TOOLKIT'] != 'gonk':
+    Library('xpcomrt')
+
+src_list = [
+    'XPCOMRTInit.cpp',
+    'XPCOMRTStubs.cpp',
+]
+
+xpcom_base_src = [
+    'nsDebugImpl.cpp',
+    'nsMemoryImpl.cpp',
+    'nsUUIDGenerator.cpp',
+]
+src_list += [
+    '/xpcom/base/%s' % s for s in xpcom_base_src
+]
+
+xpcom_build_src = [
+    'FileLocation.cpp',
+    'Services.cpp',
+]
+src_list += [
+    '/xpcom/build/%s' % s for s in xpcom_build_src
+]
+
+xpcom_components_src = [
+    'nsCategoryManager.cpp',
+    'nsComponentManager.cpp',
+]
+src_list += [
+    '/xpcom/components/%s' % s for s in xpcom_components_src
+]
+
+xpcom_ds_src = [
+    'nsObserverList.cpp',
+    'nsObserverService.cpp',
+    'nsStringEnumerator.cpp',
+    'nsSupportsPrimitives.cpp',
+]
+
+src_list += [
+    '/xpcom/ds/%s' % s for s in xpcom_ds_src
+]
+
+xpcom_glue_src = [
+    'BlockingResourceBase.cpp',
+    'nsArrayEnumerator.cpp',
+    'nsClassInfoImpl.cpp',
+    'nsCOMArray.cpp',
+    'nsCOMPtr.cpp',
+    'nsCRTGlue.cpp',
+    'nsComponentManagerUtils.cpp',
+    'nsEnumeratorUtils.cpp',
+    'GenericFactory.cpp',
+    'nsID.cpp',
+    'nsISupportsImpl.cpp',
+    'nsMemory.cpp',
+    'nsQuickSort.cpp',
+    'nsTArray.cpp',
+    'nsTObserverArray.cpp',
+    'nsThreadUtils.cpp',
+    'nsWeakReference.cpp',
+    'PLDHashTable.cpp',
+]
+src_list += [
+    '/xpcom/glue/%s' % s for s in xpcom_glue_src
+]
+
+xpcom_io_src = [
+    'nsNativeCharsetUtils.cpp',
+]
+src_list += [
+    '/xpcom/io/%s' % s for s in xpcom_io_src
+]
+
+xpcom_string_src = [
+    'nsDependentSubstring.cpp',
+    'nsPromiseFlatString.cpp',
+    'nsReadableUtils.cpp',
+    'nsString.cpp',
+    'nsStringComparator.cpp',
+    'nsStringObsolete.cpp',
+    'nsSubstring.cpp',
+    'nsSubstringTuple.cpp',
+]
+if CONFIG['INTEL_ARCHITECTURE']:
+    xpcom_string_src += ['nsUTF8UtilsSSE2.cpp']
+src_list += [
+    '/xpcom/string/%s' % s for s in xpcom_string_src
+]
+
+xpcom_threads_src = [
+    'LazyIdleThread.cpp',
+    'nsEnvironment.cpp',
+    'nsEventQueue.cpp',
+    'nsMemoryPressure.cpp',
+    'nsProcessCommon.cpp',
+    'nsThread.cpp',
+    'nsThreadManager.cpp',
+    'nsThreadPool.cpp',
+    'nsTimerImpl.cpp',
+    'TimerThread.cpp',
+]
+src_list += [
+    '/xpcom/threads/%s' % s for s in xpcom_threads_src
+]
+
+
+SOURCES += sorted(src_list)
+
+if CONFIG['INTEL_ARCHITECTURE']:
+    sse_string_path = '/xpcom/string/nsUTF8UtilsSSE2.cpp'
+    SOURCES[sse_string_path].flags += CONFIG['SSE2_FLAGS']
+
+LOCAL_INCLUDES = [
+    '!..',
+    '../base',
+    '../build',
+    '../components',
+    '../ds',
+    '../glue',
+    '../threads',
+    '/netwerk/standalone/',
+    '/xpcom/reflect/xptinfo/',
+]
+
+DEFINES['MOZILLA_INTERNAL_API'] = True
+DEFINES['MOZILLA_XPCOMRT_API'] = True
+DEFINES['MOZILLA_EXTERNAL_LINKAGE'] = True
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+SPHINX_TREES['libxpcomrt'] = 'docs'
+
+if CONFIG['GNU_CXX']:
+    CXXFLAGS += ['-Wshadow']
--- a/xpcom/moz.build
+++ b/xpcom/moz.build
@@ -19,16 +19,17 @@ DIRS += [
     'ds',
     'io',
     'components',
     'threads',
     'reflect',
     'system',
     '../chrome',
     'build',
+    'libxpcomrt',
 ]
 
 if CONFIG['OS_ARCH'] == 'WINNT' and CONFIG['MOZ_DEBUG']:
     DIRS += ['windbgdlg']
 
 TEST_DIRS += [
     'tests',
 ]
--- a/xpcom/threads/LazyIdleThread.cpp
+++ b/xpcom/threads/LazyIdleThread.cpp
@@ -174,18 +174,20 @@ LazyIdleThread::EnsureThread()
   }
 
   return NS_OK;
 }
 
 void
 LazyIdleThread::InitThread()
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   char aLocal;
   profiler_register_thread(mName.get(), &aLocal);
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   PR_SetCurrentThreadName(mName.get());
 
   // Happens on mThread but mThread may not be set yet...
 
   nsCOMPtr<nsIThreadInternal> thread(do_QueryInterface(NS_GetCurrentThread()));
   MOZ_ASSERT(thread, "This should always succeed!");
 
@@ -206,17 +208,19 @@ LazyIdleThread::CleanupThread()
 
   {
     MutexAutoLock lock(mMutex);
 
     MOZ_ASSERT(!mThreadIsShuttingDown, "Shouldn't be true ever!");
     mThreadIsShuttingDown = true;
   }
 
+#if !defined(MOZILLA_XPCOMRT_API)
   profiler_unregister_thread();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 }
 
 void
 LazyIdleThread::ScheduleTimer()
 {
   ASSERT_OWNING_THREAD();
 
   bool shouldSchedule;
--- a/xpcom/threads/nsThread.cpp
+++ b/xpcom/threads/nsThread.cpp
@@ -1,17 +1,19 @@
 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
 /* 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/. */
 
 #include "nsThread.h"
 
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "base/message_loop.h"
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
 // Chromium's logging can sometimes leak through...
 #ifdef LOG
 #undef LOG
 #endif
 
 #include "mozilla/ReentrantMonitor.h"
 #include "nsMemoryPressure.h"
@@ -19,20 +21,22 @@
 #include "nsIClassInfoImpl.h"
 #include "nsAutoPtr.h"
 #include "nsCOMPtr.h"
 #include "nsQueryObject.h"
 #include "pratom.h"
 #include "mozilla/CycleCollectedJSRuntime.h"
 #include "mozilla/Logging.h"
 #include "nsIObserverService.h"
+#if !defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/HangMonitor.h"
 #include "mozilla/IOInterposer.h"
 #include "mozilla/ipc/MessageChannel.h"
 #include "mozilla/ipc/BackgroundChild.h"
+#endif // defined(MOZILLA_XPCOMRT_API)
 #include "mozilla/Services.h"
 #include "nsXPCOMPrivate.h"
 #include "mozilla/ChaosMode.h"
 #include "mozilla/TimeStamp.h"
 #include "mozilla/unused.h"
 #include "nsThreadSyncDispatch.h"
 #include "LeakRefPtr.h"
 
@@ -288,17 +292,19 @@ public:
   nsThreadShutdownEvent(nsThread* aThr, nsThreadShutdownContext* aCtx)
     : mThread(aThr)
     , mShutdownContext(aCtx)
   {
   }
   NS_IMETHOD Run()
   {
     mThread->mShutdownContext = mShutdownContext;
+#if !defined(MOZILLA_XPCOMRT_API)
     MessageLoop::current()->Quit();
+#endif // !defined(MOZILLA_XPCOMRT_API)
     return NS_OK;
   }
 private:
   RefPtr<nsThread>       mThread;
   nsThreadShutdownContext* mShutdownContext;
 };
 
 //-----------------------------------------------------------------------------
@@ -359,48 +365,58 @@ SetupCurrentThreadForChaosMode()
   if (ChaosMode::randomUint32LessThan(2)) {
     SetThreadAffinity(0);
   }
 }
 
 /*static*/ void
 nsThread::ThreadFunc(void* aArg)
 {
+#if !defined(MOZILLA_XPCOMRT_API)
   using mozilla::ipc::BackgroundChild;
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   nsThread* self = static_cast<nsThread*>(aArg);  // strong reference
   self->mThread = PR_GetCurrentThread();
   SetupCurrentThreadForChaosMode();
 
   // Inform the ThreadManager
   nsThreadManager::get()->RegisterCurrentThread(self);
 
+#if !defined(MOZILLA_XPCOMRT_API)
   mozilla::IOInterposer::RegisterCurrentThread();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   // Wait for and process startup event
   nsCOMPtr<nsIRunnable> event;
   {
     MutexAutoLock lock(self->mLock);
     if (!self->mEvents->GetEvent(true, getter_AddRefs(event), lock)) {
       NS_WARNING("failed waiting for thread startup event");
       return;
     }
   }
   event->Run();  // unblocks nsThread::Init
   event = nullptr;
 
   {
+#if defined(MOZILLA_XPCOMRT_API)
+    while(!self->mShutdownContext) {
+      NS_ProcessNextEvent();
+    }
+#else
     // Scope for MessageLoop.
     nsAutoPtr<MessageLoop> loop(
       new MessageLoop(MessageLoop::TYPE_MOZILLA_NONMAINTHREAD));
 
     // Now, process incoming events...
     loop->Run();
 
     BackgroundChild::CloseForCurrentThread();
+#endif // defined(MOZILLA_XPCOMRT_API)
 
     // NB: The main thread does not shut down here!  It shuts down via
     // nsThreadManager::Shutdown.
 
     // Do NS_ProcessPendingEvents but with special handling to set
     // mEventsAreDoomed atomically with the removal of the last event. The key
     // invariant here is that we will never permit PutEvent to succeed if the
     // event would be left in the queue after our final call to
@@ -420,17 +436,19 @@ nsThread::ThreadFunc(void* aArg)
           self->mEventsAreDoomed = true;
           break;
         }
       }
       NS_ProcessPendingEvents(self);
     }
   }
 
+#if !defined(MOZILLA_XPCOMRT_API)
   mozilla::IOInterposer::UnregisterCurrentThread();
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   // Inform the threadmanager that this thread is going away
   nsThreadManager::get()->UnregisterCurrentThread(self);
 
   // Dispatch shutdown ACK
   MOZ_ASSERT(self->mShutdownContext->terminatingThread == self);
   event = do_QueryObject(new nsThreadShutdownAckEvent(self->mShutdownContext));
   self->mShutdownContext->joiningThread->Dispatch(event, NS_DISPATCH_NORMAL);
@@ -882,38 +900,42 @@ void canary_alarm_handler(int signum)
   PR_END_MACRO
 
 NS_IMETHODIMP
 nsThread::ProcessNextEvent(bool aMayWait, bool* aResult)
 {
   LOG(("THRD(%p) ProcessNextEvent [%u %u]\n", this, aMayWait,
        mNestedEventLoopDepth));
 
+#if !defined(MOZILLA_XPCOMRT_API)
   // If we're on the main thread, we shouldn't be dispatching CPOWs.
   if (mIsMainThread == MAIN_THREAD) {
     ipc::CancelCPOWs();
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   if (NS_WARN_IF(PR_GetCurrentThread() != mThread)) {
     return NS_ERROR_NOT_SAME_THREAD;
   }
 
   // The toplevel event loop normally blocks waiting for the next event, but
   // if we're trying to shut this thread down, we must exit the event loop when
   // the event queue is empty.
   // This only applys to the toplevel event loop! Nested event loops (e.g.
   // during sync dispatch) are waiting for some state change and must be able
   // to block even if something has requested shutdown of the thread. Otherwise
   // we'll just busywait as we endlessly look for an event, fail to find one,
   // and repeat the nested event loop since its state change hasn't happened yet.
   bool reallyWait = aMayWait && (mNestedEventLoopDepth > 0 || !ShuttingDown());
 
+#if !defined(MOZILLA_XPCOMRT_API)
   if (MAIN_THREAD == mIsMainThread && reallyWait) {
     HangMonitor::Suspend();
   }
+#endif // !defined(MOZILLA_XPCOMRT_API)
 
   // Fire a memory pressure notification, if we're the main thread and one is
   // pending.
   if (MAIN_THREAD == mIsMainThread && !ShuttingDown()) {
     MemoryPressureState mpPending = NS_GetPendingMemoryPressure();
     if (mpPending != MemPressure_None) {
       nsCOMPtr<nsIObserverService> os = services::GetObserverService();
 
@@ -983,19 +1005,21 @@ nsThread::ProcessNextEvent(bool aMayWait
       MutexAutoLock lock(mLock);
       mEvents->GetEvent(reallyWait, getter_AddRefs(event), lock);
     }
 
     *aResult = (event.get() != nullptr);
 
     if (event) {
       LOG(("THRD(%p) running [%p]\n", this, event.get()));
+#if !defined(MOZILLA_XPCOMRT_API)
       if (MAIN_THREAD == mIsMainThread) {
         HangMonitor::NotifyActivity();
       }
+#endif // !defined(MOZILLA_XPCOMRT_API)
       event->Run();
     } else if (aMayWait) {
       MOZ_ASSERT(ShuttingDown(),
                  "This should only happen when shutting down");
       rv = NS_ERROR_UNEXPECTED;
     }
   }
 
--- a/xpcom/threads/nsTimerImpl.cpp
+++ b/xpcom/threads/nsTimerImpl.cpp
@@ -459,18 +459,20 @@ nsTimerImpl::SetTarget(nsIEventTarget* a
 
 void
 nsTimerImpl::Fire()
 {
   if (mCanceled) {
     return;
   }
 
+#if !defined(MOZILLA_XPCOMRT_API)
   PROFILER_LABEL("Timer", "Fire",
                  js::ProfileEntry::Category::OTHER);
+#endif
 
   TimeStamp now = TimeStamp::Now();
   if (MOZ_LOG_TEST(GetTimerLog(), LogLevel::Debug)) {
     TimeDuration   a = now - mStart; // actual delay in intervals
     TimeDuration   b = TimeDuration::FromMilliseconds(mDelay); // expected delay in intervals
     TimeDuration   delta = (a > b) ? a - b : b - a;
     uint32_t       d = delta.ToMilliseconds(); // delta in ms
     sDeltaSum += d;